• 大数据ClickHouse(十二):MergeTree系列表引擎之CollapsingMergeTree


    文章目录

    MergeTree系列表引擎之CollapsingMergeTree

    一、CollapsingMergeTree基本讲解

    二、测试实例

    1、按照顺序写入需要更新或删除的数据

    2、乱序写入需要更新或删除的数据


    MergeTree系列表引擎之CollapsingMergeTree

    一、CollapsingMergeTree基本讲解

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

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

    • CollapsingMergeTree建表语法如下:
    1. CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
    2. (
    3. name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    4. name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    5. ...
    6. sign Int8
    7. ) ENGINE = CollapsingMergeTree(sign)
    8. [PARTITION BY expr]
    9. [ORDER BY expr]
    10. [SAMPLE BY expr]
    11. [SETTINGS name=value, ...]

    存在的问题:

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

    数据折叠保留规则:

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

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

    二、测试实例

    1、按照顺序写入需要更新或删除的数据

    1. #创建表 t_collapsing_mt ,使用CollapsingMergeTree
    2. node1 :) create table t_collapsing_mt(
    3. :-] id UInt8,
    4. :-] name String,
    5. :-] loc String,
    6. :-] login_times UInt8,
    7. :-] total_dur UInt8,
    8. :-] sign Int8
    9. :-] )engine = CollapsingMergeTree(sign)
    10. :-] order by (id,total_dur)
    11. :-] primary key id
    12. :-] partition by loc
    13. :-] ;
    14. #向表 t_collapsing_mt 中插入以下数据:
    15. node1 :) insert into t_collapsing_mt values(1,'张三','北京',1,30,1),(2,'李四','上海',1,40,1)
    16. #查看表 t_collapsing_mt中的数据
    17. node1 :) select * from t_collapsing_mt;
    18. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    19. │ 2 │ 李四 │ 上海 │ 1 │ 40 │ 1 │
    20. └────┴─────┴──────┴───────────┴──────────┴─────┘
    21. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    22. │ 1 │ 张三 │ 北京 │ 1 │ 30 │ 1 │
    23. └────┴─────┴──────┴───────────┴─────────┴──────┘
    24. #向表 t_collapsing_mt中继续插入一条数据,删除“张三”数据
    25. node1 :) insert into t_collapsing_mt values(1,'张三','北京',1,30,-1);
    26. #查询表 t_collapsing_mt 中的数据
    27. node1 :) select * from t_collapsing_mt;
    28. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    29. │ 1 │ 张三 │ 北京 │ 1 │ 30 │ 1 │
    30. └────┴─────┴──────┴───────────┴──────────┴─────┘
    31. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    32. │ 2 │ 李四 │ 上海 │ 1 │ 40 │ 1 │
    33. └───┴─────┴──────┴────────────┴──────────┴─────┘
    34. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    35. │ 1 │ 张三 │ 北京 │ 1 │ 30 │ -1 │
    36. └────┴─────┴──────┴───────────┴─────────┴─────┘
    37. #手动触发 optimize 合并相同分区数据
    38. node1 :) optimize table t_collapsing_mt;
    39. #查询表 t_collapsing_mt 中的数据
    40. node1 :) select * from t_collapsing_mt;
    41. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    42. │ 2 │ 李四 │ 上海 │ 1 │ 40 │ 1 │
    43. └───┴─────┴──────┴────────────┴──────────┴─────┘
    44. #插入以下两条数据,来更新 “李四”数据
    45. node1 :) insert into t_collapsing_mt values(2,'李四','上海',1,40,-1),(2,'李四','上海',2,100,1);
    46. #查询表 t_collapsing_mt 中的数据
    47. node1 :) select * from t_collapsing_mt;
    48. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    49. │ 2 │ 李四 │ 上海 │ 1 │ 40 │ 1 │
    50. └────┴──────┴──────┴─────────────┴───────────┴──────┘
    51. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    52. │ 2 │ 李四 │ 上海 │ 1 │ 40 │ -1 │
    53. │ 2 │ 李四 │ 上海 │ 2 │ 100 │ 1 │
    54. └────┴──────┴──────┴─────────────┴───────────┴──────┘
    55. #手动执行 optimize 触发相同分区合并
    56. node1 :) optimize table t_collapsing_mt;
    57. #查看表 t_collapsing_mt中的数据
    58. node1 :) select * from t_collapsing_mt;
    59. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    60. │ 2 │ 李四 │ 上海 │ 2 │ 100 │ 1 │
    61. └────┴──────┴──────┴─────────────┴───────────┴──────┘

    注意:以上功能使用 collapsingMergeTree实现了分区合并。

    2、乱序写入需要更新或删除的数据

    1. #删除表 t_collapsing_mt ,重新创建表 t_collapsing_mt
    2. 这里建表语句与之前一样
    3. #向表 t_collapsing_mt 中插入以下数据:
    4. node1 :) insert into t_collapsing_mt values(1,'张三','北京',1,30,-1),(1,'张三','北京',1,30,1),(2,'李四','上海',1,40,1)
    5. #查询表 t_collapsing_mt中的数据
    6. node1 :) select * from t_collapsing_mt;
    7. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    8. │ 2 │ 李四 │ 上海 │ 1 │ 40 │ 1 │
    9. └────┴──────┴──────┴─────────────┴───────────┴──────┘
    10. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    11. │ 1 │ 张三 │ 北京 │ 1 │ 30 │ -1 │
    12. │ 1 │ 张三 │ 北京 │ 1 │ 30 │ 1 │
    13. └────┴──────┴──────┴─────────────┴───────────┴──────┘
    14. #手动执行 optimize 命令,合并相同分区数据
    15. node1 :) optimize table t_collapsing_mt;
    16. #查询表 t_collapsing_mt表中的数据,数据没有变化
    17. node1 :) select * from t_collapsing_mt;
    18. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    19. │ 2 │ 李四 │ 上海 │ 1 │ 40 │ 1 │
    20. └────┴──────┴──────┴─────────────┴───────────┴──────┘
    21. ┌─id─┬─name─┬─loc──┬─login_times─┬─total_dur─┬─sign─┐
    22. │ 1 │ 张三 │ 北京 │ 1 │ 30 │ -1 │
    23. │ 1 │ 张三 │ 北京 │ 1 │ 30 │ 1 │

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

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


    • 📢博客主页:https://lansonli.blog.csdn.net
    • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
    • 📢本文由 Lansonli 原创,首发于 CSDN博客🙉
    • 📢停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活✨
  • 相关阅读:
    Quest商店:利用A/B测试,竟可将VR游戏转化率提升26.5%
    【云原生】k8s集群调度
    jenkins 部署spring-boot 项目
    【华为机试真题 Python实现】喊 7 的次数重排
    Java中java.util.Arrays参考指南
    SpringBoot入门到精通-基于阿里云短信服务-定义Starter封装通用组件
    用好技巧,文件夹、文件重命名其实很简单
    Redis安装及使用(Windows&&Linux)
    网页语音合成API运行无效果问题处理
    C#开发 降.NET版本问题解决笔记
  • 原文地址:https://blog.csdn.net/xiaoweite1/article/details/126358042