ClickHouse(十六):Clickhouse MergeTree系列表引擎 - CollapsingMergeTree

 进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容!

个人主页:含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客

订阅:拥抱独家专题,你的订阅将点燃我的创作热情!

点赞:赞同优秀创作,你的点赞是对我创作最大的认可!

⭐️ 收藏:收藏原创博文,让我们一起打造IT界的荣耀与辉煌!

✏️评论:留下心声墨迹,你的评论将是我努力改进的方向!


目录

1. CollapsingMergeTree建表语法

2. 存在的问题

3. 数据折叠保留规则

4. 示例


CollapsingMergeTree就是一种通过以增代删的思路,支持行级数据修改和删除的表引擎。它通过定义一个sign标记位字段,记录数据行的状态。如果sign标记为1,则表示这是一行有效的数据;如果sign标记为-1,则表示这行数据需要被删除。当CollapsingMergeTree分区合并时,同一数据分区内,sign标记为1和-1的一组数据会被抵消删除。

每次需要新增数据时,写入一行sign标记为1的数据;需要删除数据时,则写入一行sign标记为-1的数据。此外,只有相同分区内的数据才有可能被折叠。

1. CollapsingMergeTree建表语法

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]

(

    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],

    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],

...

sign Int8

) ENGINE = CollapsingMergeTree(sign)

[PARTITION BY expr]

[ORDER BY expr]

[SAMPLE BY expr]

[SETTINGS name=value, ...]

2. 存在的问题

CollapsingMergeTree对于写入数据的顺序有着严格要求,否则导致无法正常折叠。

3. 数据折叠保留规则

在同一个分区内order by 字段相同的数据存在多条,且sign值不同,数据保留规则如下:

  1. 如果sign=1和sign=-1的行数相同并且最后一行数据sign=1,则保留第一行sign=-1的行和最后一行sign=1的行。
  2. 如果sign=1的行比sign=-1的行多,则保留最后一条sign=1的行。
  3. 如果sign=-1的行比sign=1的行多,则保留第一条sign=-1的行。
  4. 其他情况,不保留数据。

4. 示例

  • 按照顺序写入需要更新或删除的数据:
#创建表 t_collapsing_mt ,使用CollapsingMergeTree

node1 :) create table t_collapsing_mt(

:-] id UInt8,

:-] name String,

:-] loc String,

:-] login_times UInt8,

:-] total_dur UInt8,

:-] sign Int8

:-] )engine = CollapsingMergeTree(sign)

:-] order by (id,total_dur)

:-] primary key id

:-] partition by loc

:-] ;



#向表   t_collapsing_mt 中插入以下数据:

node1 :) insert into t_collapsing_mt values(1,'张三','北京',1,30,1),(2,'李四','上海',1,40,1)



#查看表 t_collapsing_mt中的数据

node1 :) select * from t_collapsing_mt;

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2  │ 李四   │ 上海   │           1    │        40   │    1  │

└────┴─────┴──────┴───────────┴──────────┴─────┘

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  1   │ 张三  │ 北京   │           1   │        30   │    1   │

└────┴─────┴──────┴───────────┴─────────┴──────┘



#向表 t_collapsing_mt中继续插入一条数据,删除“张三”数据

node1 :) insert into t_collapsing_mt values(1,'张三','北京',1,30,-1);



#查询表 t_collapsing_mt 中的数据

node1 :) select * from t_collapsing_mt;

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  1   │ 张三  │ 北京   │           1   │        30    │    1  │

└────┴─────┴──────┴───────────┴──────────┴─────┘

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2 │ 李四   │ 上海   │           1     │        40   │    1  │

└───┴─────┴──────┴────────────┴──────────┴─────┘

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  1  │ 张三   │ 北京  │           1     │        30   │    -1 │

└────┴─────┴──────┴───────────┴─────────┴─────┘



#手动触发 optimize 合并相同分区数据

node1 :) optimize table t_collapsing_mt;



#查询表 t_collapsing_mt 中的数据

node1 :) select * from t_collapsing_mt;

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2 │ 李四   │ 上海   │           1     │        40   │    1  │

└───┴─────┴──────┴────────────┴──────────┴─────┘





#插入以下两条数据,来更新 “李四”数据

node1 :) insert into t_collapsing_mt values(2,'李四','上海',1,40,-1),(2,'李四','上海',2,100,1);



#查询表 t_collapsing_mt 中的数据

node1 :) select * from t_collapsing_mt;

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2  │ 李四  │ 上海  │           1    │        40   │    1 │

└────┴──────┴──────┴─────────────┴───────────┴──────┘

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2  │  李四 │ 上海  │           1   │        40   │   -1  │

│  2  │ 李四  │ 上海  │           2   │       100   │    1  │

└────┴──────┴──────┴─────────────┴───────────┴──────┘



#手动执行 optimize 触发相同分区合并

node1 :) optimize table t_collapsing_mt;



#查看表 t_collapsing_mt中的数据

node1 :) select * from t_collapsing_mt;

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2  │ 李四  │ 上海  │           2    │       100  │    1  │

└────┴──────┴──────┴─────────────┴───────────┴──────┘



注意:以上功能使用 collapsingMergeTree实现了分区合并。
  • 乱序写入需要更新或删除的数据:
#删除表 t_collapsing_mt ,重新创建表 t_collapsing_mt

这里建表语句与之前一样



#向表 t_collapsing_mt 中插入以下数据:

node1 :) insert into t_collapsing_mt values(1,'张三','北京',1,30,-1),(1,'张三','北京',1,30,1),(2,'李四','上海',1,40,1)



#查询表 t_collapsing_mt中的数据

node1 :) select * from t_collapsing_mt;

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2  │ 李四  │ 上海  │           1   │        40   │    1  │

└────┴──────┴──────┴─────────────┴───────────┴──────┘

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  1  │ 张三  │ 北京  │           1   │        30   │   -1  │

│  1  │ 张三  │ 北京  │           1   │        30   │    1  │

└────┴──────┴──────┴─────────────┴───────────┴──────┘



#手动执行 optimize 命令,合并相同分区数据

node1 :) optimize table t_collapsing_mt;



#查询表 t_collapsing_mt表中的数据,数据没有变化

node1 :) select * from t_collapsing_mt;

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  2  │ 李四  │ 上海  │           1   │        40   │    1  │

└────┴──────┴──────┴─────────────┴───────────┴──────┘

┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐

│  1  │ 张三  │ 北京  │           1   │        30   │   -1  │

│  1  │ 张三  │ 北京  │           1   │        30   │    1  │

└────┴──────┴──────┴─────────────┴───────────┴──────┘



注意:当数据插入到表中的顺序标记如果不是1,-1这种顺序时,合并相同分区内的数据不能达到修改和更新效果。

如果数据的写入程序是单线程执行的,则能够较好地控制写入顺序;如果需要处理的数据量很大,数据的写入程序通常是多线程执行的,那么此时就不能保障数据的写入顺序了。在这种情况下,CollapsingMergeTree的工作机制就会出现问题。但是可以通过VersionedCollapsingMergeTree的表引擎得到解决。


‍如需博文中的资料请私信博主。


你可能感兴趣的:(大数据OLAP体系技术栈,clickhouse,数据库,分布式数据库,数据仓库,实时数仓)