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

MAP

MAP

概要

MAPは、キーと値のペアのセットを保存する複雑なデータ型です。たとえば、{a:1, b:2, c:3}のような形式です。MAP内のキーは一意である必要があります。ネストされたMAPは最大14段階のネスティングが可能です。

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

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

構文

MAP<キーのデータ型,値のデータ型>
  • キーのデータ型:キーのデータ型です。キーは、数値、文字列、または日付など、StarRocksでサポートされているプリミティブなデータ型である必要があります。HLL、JSON、ARRAY、MAP、BITMAP、STRUCTのいずれかのデータ型ではないことが制約されています。
  • 値のデータ型:値のデータ型です。値は任意のサポートされているデータ型であることができます。

キーと値はネイティブにnull許容です。

StarRocksでのMAP列の定義

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

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

-- ネストされたMAPを定義する。
CREATE TABLE t1(
c0 INT,
c1 MAP<DATE, MAP<VARCHAR(10), INT>>
)
DUPLICATE KEY(c0);

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

MAP型のカラムには以下の制約があります:

  • テーブルのキーカラムとして使用することはできません。値カラムとしてのみ使用できます。
  • テーブルのパーティションキーカラム(PARTITION BYに続くカラム)として使用することはできません。
  • テーブルのバケティングカラム(DISTRIBUTED BYに続くカラム)として使用することはできません。

SQLでのMAPの構築

MAPは、次の2つの構文を使用してSQLで構築することができます。

  • map{キーの式:値の式, ...}: MAPの要素はカンマ(,)で区切られ、キーと値はコロン(:)で区切られます。例:map{a:1, b:2, c:3}
  • map(キーの式, 値の式, ... ): キーと値の式はペアでなければなりません。例:map(a,1,b,2,c,3)

StarRocksは、すべての入力のキーと値から、キーと値のデータ型を推論することができます。

select map{1:1, 2:2, 3:3} as numbers;
select map(1,1,2,2,3,3) as numbers; -- {1:1,2:2,3:3}を返します。
select map{1:"apple", 2:"orange", 3:"pear"} as fruit;
select map(1, "apple", 2, "orange", 3, "pear") as fruit; -- {1:"apple",2:"orange",3:"pear"}を返します。
select map{true:map{3.13:"abc"}, false:map{}} as nest;
select map(true, map(3.13, "abc"), false, map{}) as nest; -- {1:{3.13:"abc"},0:{}}を返します。

キーまたは値のデータ型が異なる場合、StarRocksは適切な型(上位型)を自動的に推論します。

select map{1:2.2, 1.2:21} as floats_floats; -- {1.0:2.2,1.2:21.0}を返します。
select map{12:"a", "100":1, NULL:NULL} as string_string; -- {"12":"a","100":"1",null:null}を返します。

また、MAPを構築する際に<>を使用してデータ型を指定することもできます。入力のキーまたは値は、指定された型にキャスト可能である必要があります。

select map<FLOAT,INT>{1:2}; -- {1:2}を返します。
select map<INT,INT>{"12": "100"}; -- {12:100}を返します。

キーと値はnull許容です。

select map{1:NULL};

空のMAPを構築することもできます。

select map{} as empty_map;
select map() as empty_map; -- {}を返します。

StarRocksへのMAPデータのロード

MAPデータをStarRocksには2つの方法でロードすることができます:INSERT INTOORC/Parquetのローディング

MAPデータのロード時、StarRocksは各MAP内の重複するキーを削除します。

INSERT INTO

  CREATE TABLE t0(
c0 INT,
c1 MAP<INT,INT>
)
DUPLICATE KEY(c0);

INSERT INTO t0 VALUES(1, map{1:2,3:NULL});

ORCおよびParquetファイルからのMAPデータのロード

StarRocksのMAPデータ型は、ORCまたはParquet形式のMAP構造に対応します。追加の仕様は必要ありません。ORC/Parquetのローディングの手順に従って、ORCまたはParquetファイルからMAPデータをロードすることができます。

MAPデータへのアクセス

例1:テーブルt0のMAP列c1をクエリする。

mysql> select c1 from t0;
+--------------+
| c1 |
+--------------+
| {1:2,3:null} |
+--------------+

例2:キーによってMAPから値を取得するために[ ]演算子を使用するか、またはelement_at(any_map, any_key)関数を使用します。

次の例では、キー1に対応する値をクエリします。

mysql> select map{1:2,3:NULL}[1];
+-----------------------+
| map(1, 2, 3, NULL)[1] |
+-----------------------+
| 2 |
+-----------------------+

mysql> select element_at(map{1:2,3:NULL},1);
+--------------------+
| map{1:2,3:NULL}[1] |
+--------------------+
| 2 |
+--------------------+

キーがMAP内に存在しない場合は、NULLが返されます。

次の例では、存在しないキー2に対応する値をクエリします。

mysql> select map{1:2,3:NULL}[2];
+-----------------------+
| map(1, 2, 3, NULL)[2] |
+-----------------------+
| NULL |
+-----------------------+

例3:多次元MAPを再帰的にクエリする。

次の例では、まずキー1に対応する値map{2:1}をクエリし、そしてmap{2:1}内のキー2に対応する値を再帰的にクエリします。

mysql> select map{1:map{2:1},3:NULL}[1][2];

+----------------------------------+
| map(1, map(2, 1), 3, NULL)[1][2] |
+----------------------------------+
| 1 |
+----------------------------------+

参考