メインコンテンツまでスキップ

STRUCT

STRUCT

概要

STRUCTは複雑なデータ型を表現するために広く使用されています。これは、異なるデータ型からなる要素(フィールドとも呼ばれます)のコレクションを表します。例えば、<a INT, b STRING>のようなものです。

STRUCT内のフィールド名は一意でなければなりません。フィールドはプリミティブデータ型(数値、文字列、日付など)や複雑なデータ型(ARRAYやMAPなど)であることができます。

STRUCT内のフィールドは、他のSTRUCTやARRAY、MAPである場合もあります。これにより、入れ子のデータ構造を作成することができます。例えば、STRUCT<a INT, b STRUCT<c INT, d INT>, c MAP<INT, INT>, d ARRAY<INT>>のようなものです。

STRUCTデータ型はv3.1以降でサポートされています。v3.1では、StarRocksテーブルを作成し、そのテーブルにSTRUCTデータをロードし、MAPデータをクエリすることができます。

v2.5以降、StarRocksはデータレイクからMAPおよびSTRUCTの複雑なデータ型のクエリをサポートしています。StarRocksが提供する外部カタログを使用して、Apache Hive™、Apache Hudi、およびApache IcebergからMAPおよびSTRUCTデータをクエリできます。ORCおよびParquetファイルからのデータのみクエリできます。外部カタログを使用して外部データソースのクエリ方法についての詳細な情報については、カタログの概要および必要なカタログタイプに関連するトピックを参照してください。

構文

STRUCT<name, type>
  • name: フィールド名は、CREATE TABLEステートメントで定義される列名と同じである必要があります。
  • type: フィールドの型です。任意のサポートされている型であることができます。

StarRocksでSTRUCT列を定義する

テーブルを作成し、この列にSTRUCTデータをロードする際にSTRUCT列を定義することができます。

-- 1次元のstructを定義する。
CREATE TABLE t0(
c0 INT,
c1 STRUCT<a INT, b INT>
)
DUPLICATE KEY(c0);

-- 複雑なstructを定義する。
CREATE TABLE t1(
c0 INT,
c1 STRUCT<a INT, b STRUCT<c INT, d INT>, c MAP<INT, INT>, d ARRAY<INT>>
)
DUPLICATE KEY(c0);

-- NOT NULLのstructを定義する。
CREATE TABLE t2(
c0 INT,
c1 STRUCT<a INT, b INT> NOT NULL
)
DUPLICATE KEY(c0);

STRUCT型の列には、以下の制限があります。

  • テーブルのキーカラムでは使用できません。値カラムとしてのみ使用できます。
  • テーブルのパーティションキーカラム(PARTITION BYの後)として使用できません。
  • テーブルのバケット列(DISTRIBUTED BYの後)として使用できません。
  • 集約テーブルの値カラムとして使用する場合、replace()関数のみサポートされます。

SQLでstructを構築する

STRUCTは、SQLを使用して次の関数を使用して構築することができます:row, struct、およびnamed_struct。 struct()はrow()の別名です。

  • rowおよびstructは、非名前付きのstructをサポートしています。フィールド名を指定する必要はありません。StarRocksは自動的に列名(col1col2など)を生成します。
  • named_structは名前付きのstructをサポートしています。名前と値の式はペアである必要があります。

StarRocksは、入力値に基づいてstructの型を自動的に決定します。

select row(1, 2, 3, 4) as numbers; -- {"col1":1,"col2":2,"col3":3,"col4":4}を返します。
select row(1, 2, null, 4) as numbers; -- {"col1":1,"col2":2,"col3":null,"col4":4}を返します。
select row(null) as nulls; -- {"col1":null}を返します。
select struct(1, 2, 3, 4) as numbers; -- {"col1":1,"col2":2,"col3":3,"col4":4}を返します。
select named_struct('a', 1, 'b', 2, 'c', 3, 'd', 4) as numbers; -- {"a":1,"b":2,"c":3,"d":4}を返します。

STRUCTデータのロード

STRUCTデータをStarRocksには、INSERT INTOORC/Parquet loadingの2つの方法でロードすることができます。

注意:StarRocksはデータ型を対応するSTRUCT型に自動的にキャストします。

INSERT INTO

CREATE TABLE t0(
c0 INT,
c1 STRUCT<a INT, b INT>
)
DUPLICATE KEY(c0);

INSERT INTO t0 VALUES(1, row(1, 1));

SELECT * FROM t0;
+------+---------------+
| c0 | c1 |
+------+---------------+
| 1 | {"a":1,"b":1} |
+------+---------------+

ORC/ParquetファイルからSTRUCTデータをロードする

StarRocksのSTRUCTデータ型は、ORCまたはParquet形式のネストした列構造に対応しています。追加の指定は必要ありません。ORCまたはParquetファイルからSTRUCTデータをロードする場合は、ORC/Parquet loadingの手順に従ってください。

STRUCTフィールドへのアクセス

Structのサブフィールドをクエリするには、ドット(.)演算子を使用してフィールド名で値をクエリするか、インデックスで値を呼び出すために[]を使用することができます。

mysql> select named_struct('a', 1, 'b', 2, 'c', 3, 'd', 4).a;
+------------------------------------------------+
| named_struct('a', 1, 'b', 2, 'c', 3, 'd', 4).a |
+------------------------------------------------+
| 1 |
+------------------------------------------------+

mysql> select row(1, 2, 3, 4).col1;
+-----------------------+
| row(1, 2, 3, 4).col1 |
+-----------------------+
| 1 |
+-----------------------+

mysql> select row(2, 4, 6, 8)[2];
+--------------------+
| row(2, 4, 6, 8)[2] |
+--------------------+
| 4 |
+--------------------+

mysql> select row(map{'a':1}, 2, 3, 4)[1];
+-----------------------------+
| row(map{'a':1}, 2, 3, 4)[1] |
+-----------------------------+
| {"a":1} |
+-----------------------------+