ClickHouse 的 Map 类型以及相关操作(十四)
ClickHouse 的 Map 类型以及相关操作(十四)
本文来源: ( https://www.cnblogs.com/traditional/tag/ClickHouse:一款速度快到让人发指的列式存储数据库/ )
楔子
之前在介绍数据类型的时候,有一种没有说,就是 Map。Map 是什么想必无需多言,简单来说的话就是维护键值对之间的映射关系,可以通过键迅速定位到值。
下面就先来创建一张表:
1 | -- 在定义 Map 的时候,必须要指定键值对的类型 |
但是不出意外我们创建表的时候应该会报错,原因就是在表中支持定义 Map 类型的字段还只是试验性的,我们需要将 allow_experimental_map_type 设置为 1,这也是我们单独拿出来介绍的原因。然后我们插入数据:
1 | set allow_experimental_map_type = 1; |
下面来对表进行查询:
1 | SELECT * FROM table_map; |
如果想选择某个具体的键对应的 value,那么直接通过方括号即可,举个栗子:
1 | SELECT a['key1'], a['key2'], a FROM table_map; |
如果查询一个不在 Map 当中 key,那么会返回对应的零值。
1 | SELECT a['key3'] FROM table_map; |
当然我们也可以根据现有的数组结构创建 Map:
1 | WITH [1, 2, 3] AS key, ['a', 'b', 'c'] AS value |
我们在选择的时候也可以只选择 key 或者 value。
1 | SELECT a.keys, a.values FROM table_map; |
然后我们来看看字典都支持哪些函数操作
map:我们除了可以通过大括号创建 Map,也可以通过 map 函数创建
1 | SELECT map('key1', number, 'key2', number * 2) FROM numbers(3); |
同理我们插入数据的时候也可以使用 map 函数:
1 | INSERT INTO table_map VALUES (map('key1', 1, 'key2', 10)); |
mapContains:检测 Map 里面是否包含某个 key
1 | WITH map(1, 3, 2, 5) AS m |
mapKeys:等价于 Map.keys
1 | SELECT a.keys, mapKeys(a) FROM table_map; |
mapValues:等价于 Map.values
1 | SELECT a.values, mapValues(a) FROM table_map; |
注意:mapKeys、mapValues 相当于数据全量读取,然后再选择所有的 key 或 value,所以建议还是使用 Map.keys、Map.values。但如果将 optimize_functions_to_subcolumns 设置为 1,那么会进行优化:
1 | SELECT mapKeys(m), mapValues(m) FROM table 会转化成 SELECT m.keys, m.values FROM table |
以上就是 Map 的内容,总的来说还是很简单的。
JSON 的相关操作
既然提到了 Map,那么就不能不提到 JSON,这两者在结构上有着非常高的相似之处,下面就来看看 JSON 支持哪些操作。
isValidJSON:检测 JSON 是否合法
JSON 本质上也是一个字符串,isValidJSON 则是检测该字符串是否符合 JSON 格式。
1 | SELECT isValidJSON('{"a": 1, "b": false}'), isValidJSON('{1, 2, 3}'); |
JSONHas:检测 JSON 是否包含指定的 key
1 | SELECT JSONHas('{"a": 1, "b": false}', 'a'), JSONHas('{"a": 1, "b": false}', 'a1'); |
JSONLength:获取 JSON 的长度
1 | SELECT JSONLength('{"a": 1, "b": false}'); |
JSONType:获取 JSON 中指定 value 的类型
1 | WITH '{"a": 1, "b": true, "c": null, "d": "xx", "e": [1, 2, 3], "f": {"a": 1}}' AS j |
toJSONString:将其它数据类型转成 JSON
1 | -- 不可以写成 {'a': 1, 'b': 2} |
JSONExtract:根据 key,从 JSON 中解析出指定的 value,就类似于根据 key 获取 Map 中的 value 一样
1 | -- 在获取 value 的时候,必须要指定 value 是什么类型 |
如果解析失败,那么会得到相应的零值,举个栗子:
1 | WITH '{"a": [null, 123], "b": {"a": 1}}' AS j |