跳到主要内容
版本: 最新版本-3.5

MAP

MAP 是一种复杂数据类型,用于存储一组键值对,例如 {a:1, b:2, c:3}。Map 中的键必须是唯一的。嵌套 map 最多可以包含 14 层嵌套。

MAP 数据类型从 v3.1 版本开始支持。在 v3.1 中,您可以在创建 StarRocks 表时定义 MAP 列,将 MAP 数据加载到该表中,并查询 MAP 数据。

从 v2.5 版本开始,StarRocks 支持从数据湖查询复杂数据类型 MAP 和 STRUCT。您可以使用 StarRocks 提供的外部 Catalog 查询 Apache Hive™、Apache Hudi 和 Apache Iceberg 中的 MAP 和 STRUCT 数据。您只能查询 ORC 和 Parquet 文件中的数据。有关如何使用外部 Catalog 查询外部数据源的更多信息,请参见Catalog 概览以及与所需 Catalog 类型相关的文档。

语法

MAP<key_type,value_type>
  • key_type:键的数据类型。键必须是 StarRocks 支持的原始类型,例如数值、字符串或日期。它不能是 HLL、JSON、ARRAY、MAP、BITMAP 或 STRUCT 类型。
  • value_type:值的数据类型。该值可以是任何支持的类型。

键和值原生支持 NULL 值

在 StarRocks 中定义 MAP 列

您可以在创建表时定义 MAP 列,并将 MAP 数据加载到该列中。

-- Define a one-dimensional map.
CREATE TABLE t0(
c0 INT,
c1 MAP<INT,INT>
)
DUPLICATE KEY(c0);

-- Define a nested map.
CREATE TABLE t1(
c0 INT,
c1 MAP<DATE, MAP<VARCHAR(10), INT>>
)
DUPLICATE KEY(c0);

-- Define a NOT NULL map.
CREATE TABLE t2(
c0 INT,
c1 MAP<INT,DATETIME> NOT NULL
)
DUPLICATE KEY(c0);

MAP 类型的列有以下限制

  • 不能用作表中的键列。它们只能用作值列。
  • 不能用作表中的分区键列(PARTITION BY 后面的列)。
  • 不能用作表中的分桶列(DISTRIBUTED BY 后面的列)。

在 SQL 中构造 map

可以使用以下两种语法在 SQL 中构造 Map

  • map{key_expr:value_expr, ...}:Map 元素用逗号 (,) 分隔,键和值用冒号 (:) 分隔,例如 map{a:1, b:2, c:3}

  • map(key_expr, value_expr ...):键和值的表达式必须成对出现,例如 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; -- Return {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; -- Return {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; -- Return {1:{3.13:"abc"},0:{}}.

如果键或值具有不同的类型,StarRocks 会自动派生适当的类型(超类型)。

select map{1:2.2, 1.2:21} as floats_floats; -- Return {1.0:2.2,1.2:21.0}.
select map{12:"a", "100":1, NULL:NULL} as string_string; -- Return {"12":"a","100":"1",null:null}.

您还可以在构造 map 时使用 <> 定义数据类型。输入的键或值必须能够转换为指定的类型。

select map<FLOAT,INT>{1:2}; -- Return {1:2}.
select map<INT,INT>{"12": "100"}; -- Return {12:100}.

键和值都可以为 NULL。

select map{1:NULL};

构造空 map。

select map{} as empty_map;
select map() as empty_map; -- Return {}.

将 MAP 数据加载到 StarRocks

您可以使用两种方法将 map 数据加载到 StarRocks 中:INSERT INTOORC/Parquet 加载

请注意,StarRocks 在加载 MAP 数据时将删除每个 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 |
+----------------------------------+

参考