跳至主要内容

Map(K, V)

数据类型 Map(K, V) 存储键值对。

与其他数据库不同,ClickHouse 中的映射不是唯一的,即映射可以包含两个具有相同键的元素。(原因是映射在内部实现为 Array(Tuple(K, V)))。

可以使用语法 m[k] 获取映射 m 中键 k 的值。此外,m[k] 会扫描映射,即操作的运行时间与映射的大小成线性关系。

参数

  • K — 映射键的类型。除了 NullableLowCardinalityNullable 类型嵌套之外的任意类型。
  • V — 映射值的类型。任意类型。

示例

创建一个包含 map 类型列的表

CREATE TABLE tab (m Map(String, UInt64)) ENGINE=Memory;
INSERT INTO tab VALUES ({'key1':1, 'key2':10}), ({'key1':2,'key2':20}), ({'key1':3,'key2':30});

选择 key2

SELECT m['key2'] FROM tab;

结果

┌─arrayElement(m, 'key2')─┐
│ 10 │
│ 20 │
│ 30 │
└─────────────────────────┘

如果请求的键 k 不包含在映射中,则 m[k] 返回值类型的默认值,例如整数类型的 0 和字符串类型的 ''。要检查映射中是否存在键,可以使用函数 mapContains

CREATE TABLE tab (m Map(String, UInt64)) ENGINE=Memory;
INSERT INTO tab VALUES ({'key1':100}), ({});
SELECT m['key1'] FROM tab;

结果

┌─arrayElement(m, 'key1')─┐
│ 100 │
│ 0 │
└─────────────────────────┘

将 Tuple 转换为 Map

可以使用函数 CASTTuple() 类型的数值转换为 Map() 类型的数值。

示例

查询

SELECT CAST(([1, 2, 3], ['Ready', 'Steady', 'Go']), 'Map(UInt8, String)') AS map;

结果

┌─map───────────────────────────┐
│ {1:'Ready',2:'Steady',3:'Go'} │
└───────────────────────────────┘

读取 Map 的子列

在某些情况下,为了避免读取整个映射,可以使用子列 keysvalues

示例

查询

CREATE TABLE tab (m Map(String, UInt64)) ENGINE = Memory;
INSERT INTO tab VALUES (map('key1', 1, 'key2', 2, 'key3', 3));

SELECT m.keys FROM tab; -- same as mapKeys(m)
SELECT m.values FROM tab; -- same as mapValues(m)

结果

┌─m.keys─────────────────┐
│ ['key1','key2','key3'] │
└────────────────────────┘

┌─m.values─┐
│ [1,2,3] │
└──────────┘

另请参阅