CollapsingMergeTree表引擎

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

每次需要新增数据时,写入一行sign标记为1的数据;需要删除数据时,则写入一行sign标记为-1的数据。

建表语法

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],...
) ENGINE = CollapsingMergeTree(sign)
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]

建表示例

上面的建表语句使用CollapsingMergeTree(sign),其中字段sign是一个Int8类型的字段

CREATE TABLE emp_collapsingmergetree
(emp_id     UInt16 COMMENT '员工id',name       String COMMENT '员工姓名',work_place String COMMENT '工作地点',age        UInt8 COMMENT '员工年龄',depart     String COMMENT '部门',salary     Decimal32(2) COMMENT '工资',sign       Int8
) ENGINE = CollapsingMergeTree(sign) ORDER BY (emp_id, name) PARTITION BY work_place;

使用方式

CollapsingMergeTree同样是以ORDER BY排序键作为判断数据唯一性的依据。

-- 插入新增数据,sign=1表示正常数据
INSERT INTO emp_collapsingmergetree VALUES (1,'tom','上海',25,'技术部',20000,1);-- 更新上述的数据
-- 首先插入一条与原来相同的数据(ORDER BY字段一致),并将sign置为-1
INSERT INTO emp_collapsingmergetree VALUES (1,'tom','上海',25,'技术部',20000,-1);-- 再插入更新之后的数据
INSERT INTO emp_collapsingmergetree VALUES (1,'tom','上海',25,'技术部',30000,1);-- 查看一下结果
select * from emp_collapsingmergetree ;
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │   -1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┘
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │    1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┘
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 30000.00 │    1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┘-- 执行分区合并操作
optimize table emp_collapsingmergetree;
-- 再次查询,sign=1与sign=-1的数据相互抵消了,即被删除
select * from emp_collapsingmergetree ;┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 30000.00 │    1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┘

注意点

  • 分区合并

分数数据折叠不是实时的,需要后台进行Compaction操作,用户也可以使用手动合并命令,但是效率会很低,一般不推荐在生产环境中使用。

当进行汇总数据操作时,可以通过改变查询方式,来过滤掉被删除的数据

SELECT emp_id,name,sum(salary * sign)FROM emp_collapsingmergetree GROUP BY emp_id, name HAVING sum(sign) > 0;
┌─emp_id─┬─name─┬─sum(multiply(salary, sign))─┐
│      1 │ tom  │                    30000.00 │
└────────┴──────┴─────────────────────────────┘

只有相同分区内的数据才有可能被折叠。其实,当我们修改或删除数据时,这些被修改的数据通常是在一个分区内的,所以不会产生影响。

  • 数据写入顺序

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

-- 建表
CREATE TABLE emp_collapsingmergetree_order
(emp_id     UInt16 COMMENT '员工id',name       String COMMENT '员工姓名',work_place String COMMENT '工作地点',age        UInt8 COMMENT '员工年龄',depart     String COMMENT '部门',salary     Decimal32(2) COMMENT '工资',sign       Int8
) ENGINE = CollapsingMergeTree(sign) ORDER BY (emp_id, name) PARTITION BY work_place;-- 先插入需要被删除的数据,即sign=-1的数据
INSERT INTO emp_collapsingmergetree_order VALUES (1,'tom','上海',25,'技术部',20000,-1);
-- 再插入sign=1的数据
INSERT INTO emp_collapsingmergetree_order VALUES (1,'tom','上海',25,'技术部',20000,1);
-- 查询表
SELECT * FROM emp_collapsingmergetree_order;
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │   -1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┘
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │    1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┘-- 执行合并操作
optimize table emp_collapsingmergetree_order;
-- 再次查询表
-- 旧数据依然存在
SELECT * FROM emp_collapsingmergetree_order;
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │   -1 │
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │    1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┘

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

VersionedCollapsingMergeTree表引擎

上面提到CollapsingMergeTree表引擎对于数据写入乱序的情况下,不能够实现数据折叠的效果。VersionedCollapsingMergeTree表引擎的作用与CollapsingMergeTree完全相同,它们的不同之处在于,VersionedCollapsingMergeTree对数据的写入顺序没有要求,在同一个分区内,任意顺序的数据都能够完成折叠操作。

VersionedCollapsingMergeTree使用version列来实现乱序情况下的数据折叠。

建表语法

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],...
) ENGINE = VersionedCollapsingMergeTree(sign, version)
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]

可以看出:该引擎除了需要指定一个sign标识之外,还需要指定一个UInt8类型的version版本号。

建表示例

CREATE TABLE emp_versioned
(emp_id     UInt16 COMMENT '员工id',name       String COMMENT '员工姓名',work_place String COMMENT '工作地点',age        UInt8 COMMENT '员工年龄',depart     String COMMENT '部门',salary     Decimal32(2) COMMENT '工资',sign       Int8,version    Int8
) ENGINE = VersionedCollapsingMergeTree(sign, version) ORDER BY (emp_id, name) PARTITION BY work_place;-- 先插入需要被删除的数据,即sign=-1的数据
INSERT INTO emp_versioned VALUES (1,'tom','上海',25,'技术部',20000,-1,1);
-- 再插入sign=1的数据
INSERT INTO emp_versioned VALUES (1,'tom','上海',25,'技术部',20000,1,1);
-- 在插入一个新版本数据
INSERT INTO emp_versioned VALUES (1,'tom','上海',25,'技术部',30000,1,2);-- 先不执行合并,查看表数据
select * from emp_versioned;
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┬─version─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │    1 │       1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┴─────────┘
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┬─version─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 20000.00 │   -1 │       1 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┴─────────┘
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┬─version─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 30000.00 │    1 │       2 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┴─────────┘-- 获取正确查询结果
SELECT emp_id,name,sum(salary * sign) FROM emp_versioned GROUP BY emp_id,name HAVING sum(sign) > 0;
┌─emp_id─┬─name─┬─sum(multiply(salary, sign))─┐
│      1 │ tom  │                    30000.00 │
└────────┴──────┴─────────────────────────────┘-- 手动合并
optimize table emp_versioned;-- 再次查询
select * from emp_versioned;
┌─emp_id─┬─name─┬─work_place─┬─age─┬─depart─┬───salary─┬─sign─┬─version─┐
│      1 │ tom  │ 上海       │  25 │ 技术部 │ 30000.00 │    1 │       2 │
└────────┴──────┴────────────┴─────┴────────┴──────────┴──────┴─────────┘

可见上面虽然在插入数据乱序的情况下,依然能够实现折叠的效果。之所以能够达到这种效果,是因为在定义version字段之后,VersionedCollapsingMergeTree会自动将version作为排序条件并增加到ORDER BY的末端,就上述的例子而言,最终的排序字段为ORDER BY emp_id,name,version desc

clickhouse CollapsingMergeTree表引擎相关推荐

  1. ClickHouse MergeTree表引擎和建表语句

    1. Clickhouse使用场景 ClickHouse是由俄罗斯Yandex公司开发的.面向列的数据库管理系统(DBMS),主要面向OLAP场景,用于在线分析处理查询,可以使用SQL查询实时生成数据 ...

  2. ClickHouse的表引擎介绍(三)

    文章目录 引入表引擎的概念以及特点 一.TinyLog 二.Memory 三.MergeTree 四.ReplacingMergeTree 五.SummingMergeTree 六.Integrati ...

  3. clickhouse SummingMergeTree表引擎

    该引擎继承了MergeTree引擎,当合并 SummingMergeTree 表的数据片段时,ClickHouse 会把所有具有相同主键的行合并为一行,该行包含了被合并的行中具有数值数据类型的列的汇总 ...

  4. clickhouse Aggregatingmergetree表引擎

    Aggregatingmergetree表引擎 该表引擎继承自MergeTree,可以使用 AggregatingMergeTree 表来做增量数据统计聚合.如果要按一组规则来合并减少行数,则使用 A ...

  5. Clickhouse MergeTree表引擎TTL分布式实现

    目录 1. 执行SQL 2. 说明 3. TTL的运行原理 1. 执行SQL clickhouse1 :) clickhouse1 :) CREATE TABLE ttl_table_local ON ...

  6. ClickHouse表引擎到底怎么选

    引言 表引擎在ClickHouse中的作用十分关键,直接决定了数据如何存储和读取.是否支持并发读写.是否支持index.支持的query种类.是否支持主备复制等. ClickHouse提供了大约28种 ...

  7. 【ClickHouse内核】MergeTree表引擎语法结构

    目录 概述 MergeTree表引擎 表引擎特点 建表语句 建表参数描述 举个例子说明 ReplacingMergeTree表引擎 表引擎特点 建表语句 建表参数描述 举个例子说明 SummingMe ...

  8. 3、ClickHouse表引擎-MergeTree引擎

    ClickHouse系列文章 1.ClickHouse介绍 2.clickhouse安装与简单验证(centos) 3.ClickHouse表引擎-MergeTree引擎 4.clickhouse的L ...

  9. ClickHouse MergeTree家族特殊表引擎

    在前面的文章中,我们详细介绍了ClickHouse MergeTree表引擎的使用场景.原理.数据存储结构.建表语句以及索引优化.详见<ClickHouse MergeTree表引擎和建表语句& ...

最新文章

  1. TP-GAN 侧脸修复
  2. SecureCRT中Python脚本编写学习指南
  3. boost::fusion::as_list用法的测试程序
  4. wp7 通过后台代码给ListBoxItem添加ContextMenu 属性
  5. 2013年11月份我国网络不良与垃圾短信息分析报告
  6. 质量管理系统_智慧工地管理系统,进度安全质量三合一
  7. 洛谷 | P1219 八皇后(DFS)C++
  8. Python操作Oracle
  9. 透明loading_四步搞定小菊花 Loading 动画
  10. 哪里有全面的几何画板课件制作教程
  11. 211计算机考研到985难度,普通人想考研到985/211院校到底有多难?听听他们的心声!...
  12. Python 查看已安装的软件包及版本
  13. 【工具】Hosts文件详解
  14. 检测计算机主板是否坏掉,解决办法:如何判断cpu是否坏以及主板是否坏,如何检测主板故障...
  15. 实训期间的开发过程及心得体会
  16. 哪个牌子的护眼台灯比较好?2022秋季最佳护眼灯推荐
  17. Python_第六篇 第三方安装包(1)_fancyimpute介绍及使用
  18. 高并发事务问题以及解决方案
  19. 第五章IPv6和VOIP
  20. 使用matlab设计电机控制器,matlab实验五直流电机拖动系统控制器设计.doc

热门文章

  1. mybatis 存储过程 tmp_count_MyBatis框架介绍及实战操作
  2. linux 如何避免进程killed_Linux 内核 / 进程管理 / 如何描述一个进程?
  3. html5导出错误,JavaScript:toDataUrl()抛出“安全错误:可能无法导出受污染的画布”. - 程序园...
  4. nginx清缓存,网站刷新不过来时用
  5. php判断手机 跳转代码,php判断客户端是手机设备然后跳转到手机站
  6. linux修改mdc时钟,Linux下用xsupplicant或mdc拨号上网
  7. html如何调整打印区域,怎么调整excel打印区域_教你调整excel打印区域的方法-系统城...
  8. java.sql 拒绝连接_java.sql.SQLException: ORA-01017: 用户名/口令无效; 登录被拒绝
  9. redis 失效时间单位是秒还是毫秒_redis分布式锁的这些坑,我怀疑你是假的开发...
  10. 河流淹没分析_【专题归纳】关于河流地貌的知识点整理!附中国十二条著名江河名称的由来...