本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 chaodev 即可关注。
推荐阅读:
《手摸手带你学ClickHouse》之安装部署
《手摸手带你学ClickHouse》之访问接口
《手摸手带你学ClickHouse》之导入导出数据
《手摸手带你学ClickHouse》之MergeTree系列表引擎
《手摸手带你学ClickHouse》之ReplacingMergeTree表引擎
前面的文章详细介绍了ClickHouse单机的安装部署、ClickHouse监听端口、访问接口、设置允许其他ip访问、可视化的客户端、数据的导入导出、MergeTree表引擎以及ReplacingMergeTree表引擎。本文主要内容为ClickHouse的另外一个表引擎 CollapsingMergeTree。
1、基本使用
CollapsingMergeTree(折叠合并树)是一种以增代删,支持行级数据修改和删除的表引擎。
通过定义一个sign标记位字段,1有效,-1无效,如果在合并操作时,同一个分区内,sign标记位1和-1的数据会被抵消删除,就像折叠了一样。
创建表如下:
create table tb_coll_sin_merge_tree(
id Int8,
name String,
sign Int8
)engine=CollapsingMergeTree(sign)
order by id;
插入数据:
insert into tb_coll_sin_merge_tree values(1, 'name1',1);
insert into tb_coll_sin_merge_tree values(1, 'name2',-1);
insert into tb_coll_sin_merge_tree values(2, 'name3',1);
合并数据
optimize table tb_coll_sin_merge_tree final;
合并数据后,id相同(ORDER BY排序键)的sign标记位1和-1的将抵消删除,如下所示
需要注意的是,和其他所有MergeTree变种引擎一样,这项特性只有在合并分区时才体现,同时只有相同分区内的数据才能被折叠,我们可以验证一下。
创建一个带有分区的表
create table tb_coll_sin_merge_tree2(
id Int8,
name String,
birthday Date,
sign Int8
)engine=CollapsingMergeTree(sign)
partition by birthday
order by id;
插入数据:
insert into tb_coll_sin_merge_tree2 values(1, 'name1','1996-01-01',1);
insert into tb_coll_sin_merge_tree2 values(1, 'name2','1996-01-01',-1);
insert into tb_coll_sin_merge_tree2 values(2, 'name3','1996-02-02',1);
insert into tb_coll_sin_merge_tree2 values(2, 'name4','1996-03-03',-1);
这个表使用 birthday 作为分区字段,也就是日期相同的在一个分区,合并分区时id为2的两条数据不在一个分区,id为1的在一个分区,所以最后id为2的两条数据将被保留。
合并分区:
optimize table tb_coll_sin_merge_tree2 final;
结果如下:
2、缺陷
这个引擎对数据的写入顺序有严格要求,如果先写入sign为1,再写入sign为-1的数据,能够正常折叠。但是如果将顺序置换,先写入sign为-1,再写入sign为1的数据,则不能折叠。
如下:
- 先写入sign=-1
insert into tb_coll_sin_merge_tree2 values(3, 'name1','1996-01-01',-1);
- 再写入sign=1
insert into tb_coll_sin_merge_tree2 values(3, 'name2','1996-01-01',1);
合并分区后,无法折叠,结果如下:
在实际使用中,如果写入数据是单线程执行,那还好控制。但是如果数据量很大,通常利用多线程执行,这种情况就无法保证写入顺序,为了解决这个问题,ClickHouse提供了VersionedCollapsingMergeTree表引擎,下一篇文章介绍,敬请期待。
后续将继续更新该系列,大佬超手摸手带你学ClickHouse,敬请关注!!!
觉得有帮助点个赞吧!!!
原创不易,转载请注明出处。
微信扫一扫下方二维码即可关注我的公众号