前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >尝鲜ClickHouse的Map数据类型

尝鲜ClickHouse的Map数据类型

作者头像
Nauu
发布2021-02-07 16:30:25
9.7K2
发布2021-02-07 16:30:25
举报

今天想和大家聊一聊 ClickHouse 最新添加的一种数据类型,即 Map 数据类型。与这项特性相关的两个PR是:

https://github.com/ClickHouse/ClickHouse/pull/15806

https://github.com/ClickHouse/ClickHouse/pull/18788

Map 类型在编程语言中被广泛使用,这种 Key :Value 的数据结构非常适合用于动态实体的表达。

还是按照老规矩,接下来用一个简单的示例看一看在 ClickHouse 中 Map 类型是如何使用的。

这里我使用的 CH 版本是 21.2.1.5831,下载地址:

https://repo.yandex.ru/clickhouse/rpm/testing/x86_64

Map 类型在当前的版本中是默认禁用的,所以首先需要开启它:

代码语言:javascript
复制
set allow_experimental_map_type = 1

创建一张数据表,用 Map 来实现一对多的关联关系:

代码语言:javascript
复制
CREATE TABLE test_map (  id String,  users Map(String,  UInt8)) ENGINE = MergeTree ORDER BY (id,users)
insert into test_map values ('1',{'nauu':20 , 'boness':30});insert into test_map values ('2',{'jack':35 , 'lili':22 , 'realinsight':6});

现在查询数据,可以看到键值对形式的 Users 数据被成功保存了:

代码语言:javascript
复制
SELECT    id,    usersFROM test_map
Query id: 014cf498-a4d2-4be0-a021-1eeaabd457ba
┌─id─┬─users───────────────────┐│ 1  │ {'nauu':20,'boness':30} │└────┴─────────────────────────┘┌─id─┬─users─────────────────────────────────┐│ 2  │ {'jack':35,'lili':22,'realinsight':6} │└────┴───────────────────────────────────────┘
2 rows in set. Elapsed: 0.006 sec.

我们也可以直接通过 Key 获取 Value:

代码语言:javascript
复制
SELECT    id,    users,    users['nauu']FROM test_mapWHERE (users['boness']) = 30
Query id: e4614c91-a8f3-4235-b5f6-c763932181e1
┌─id─┬─users───────────────────┬─arrayElement(users, 'nauu')─┐│ 1  │ {'nauu':20,'boness':30} │                          20 │└────┴─────────────────────────┴─────────────────────────────┘
1 rows in set. Elapsed: 0.006 sec.

观察执行日志,发现 Map 类型目前好像没有办法走索引:

代码语言:javascript
复制
InterpreterSelectQuery: MergeTreeWhereOptimizer: condition "(users['boness']) = 30" moved to PREWHER{ae4076bb-0fde-4f87-8dca-9a37da83eaad} <Debug> default.test_map (SelectExecutor): Key condition: unknown{ae4076bb-0fde-4f87-8dca-9a37da83eaad} <Trace> default.test_map (SelectExecutor): Not using primary index on part all_1_1_0{ae4076bb-0fde-4f87-8dca-9a37da83eaad} <Trace> default.test_map (SelectExecutor): Not using primary index on part all_2_2_0E

除此以外,目前 Map 类型也提供了一些函数:

代码语言:javascript
复制
SELECT    id,    mapKeys(users) AS keys,    mapValues(users) AS vals,    mapContains(users, 'realinsight') AS hasKeyFROM test_map
Query id: 076108e6-3334-42fa-b938-bc042edbb0f1
┌─id─┬─keys──────────────────────────┬─vals──────┬─hasKey─┐│ 2  │ ['jack','lili','realinsight'] │ [35,22,6] │      1 │└────┴───────────────────────────────┴───────────┴────────┘┌─id─┬─keys──────────────┬─vals────┬─hasKey─┐│ 1  │ ['nauu','boness'] │ [20,30] │      0 │└────┴───────────────────┴─────────┴────────┘
2 rows in set. Elapsed: 0.005 sec.

mapKeys 获取所有 Map 的 Keys;

mapValues 获取所有 Map 的 Values;

mapContains 判断是否包含了某个 Key。

大家一看便知,我就不再赘述了。

除了基础数据类型之外,Map 也可以使用复合数据类型:

代码语言:javascript
复制
select map('nauu', [1,2,3,4,5], 'jack' , [101,202,30]) as map, mapKeys(map) keys, mapValues(map) vals 
Query id: 08fb6c79-8580-481a-9d35-0ec70349d152
┌─map──────────────────────────────────────┬─keys────────────┬─vals───────────────────────┐│ {'nauu':[1,2,3,4,5],'jack':[101,202,30]} │ ['nauu','jack'] │ [[1,2,3,4,5],[101,202,30]] │└──────────────────────────────────────────┴─────────────────┴────────────────────────────┘
1 rows in set. Elapsed: 0.003 sec.

可以看到在上面这个例子中,直接使用 map 函数构造 Map 数据。

在 ClickHouse 引入 Map 类型之后,我觉得对于 JSON 格式的支持也变相得到了提升,可以把 JSON 格式转换成 Map 的形式保存:

代码语言:javascript
复制
CREATE TABLE test_config (  id String,  config Map(String,  String)) ENGINE = MergeTree ORDER BY id
insert into test_config values ('1',{'title':'窗口1' , 'size':'30', 'pool':'50', 'timeout':'10'});insert into test_config values ('2',{'title':'窗口2' , 'size':'500', 'pool':'120', 'timeout':'15'});

也可以进行聚合查询:

代码语言:javascript
复制
SELECT    title,    avg(pool)FROM (    SELECT        config['title'] AS title,        toInt8(config['pool']) AS pool    FROM test_config)GROUP BY title
Query id: b202e1f2-fd15-42b3-96c1-9b5920bec1f5
┌─title─┬─avg(pool)─┐│ 窗口1 │        50 ││ 窗口2 │       120 │└───────┴───────────┘
2 rows in set. Elapsed: 0.007 sec.

好了,今天的分享就到这里吧。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ClickHouse的秘密基地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档