ClickHouse 中的主键,和其他数据库不太一样, 它只提供了数据的一级索引,但是却
不是唯一约束 。这就意味着是可以存在相同 primary key 的数据的。
主键的设定主要依据是查询语句中的 where 条件
根据条件通过对主键进行某种形式的二分查找,能够定位到对应的 index granularity,
避免了全表扫描。
index granularity:
直接翻译的话就是索引粒度,指在稀疏索引中两个相邻索引对
应数据的间隔。ClickHouse 中的 MergeTree 默认是 8192。官方不建议修改这个值,除非
该列存在大量重复值,比如在一个分区中几万行才有一个不同数据。
稀疏索引的好处就是可以用很少的索引数据,定位更多的数据,代价就是只能定位到索
引粒度的第一行,然后再进行进行一点扫描。
4.4.3 order by(必选)
order by 设定了 分区内 的数据按照哪些字段顺序进行有序保存。
order by 是 MergeTree 中唯一一个必填项,甚至比 primary key 还重要,因为当用
户不设置主键的情况,很多处理会依照 order by 的字段进行处理(比如后面会讲的去重和
汇总)
要求:主键必须是 order by 字段的前缀字段。
比如 order by 字段是 (id,sku_id) 那么主键必须是 id 或者(id,sku_id)
4.4.4 二级索引
目前在 ClickHouse 的官网上二级索引的功能是被标注为 实验性 的。
(1)使用二级索引前需要增加设置
是否允许使用实验性的二级索引
set allow_experimental_data_skipping_indices=1;
(2)创建测试表
其中 GRANULARITY N 是设定二级索引对于一级索引粒度的粒度。
(3)插入数据
(4)对比效果
那么在使用下面语句进行测试,可以看出二级索引能够为非主键字段的查询发挥作用。
4.4.5 数据 TTL
TTL 即 Time To Live,MergeTree 提供了可以管理数据或者列的生命周期的功能。
(1)列级别 TTL
➢ 创建测试表
➢ 插入数据(注意:根据实际时间改变)
➢ 手动合并,查看效果 到期后,指定的字段数据归 0
(2)表级 TTL
下面的这条语句是数据会在 create_time 之后 10 秒丢失
alter table t_order_mt3 MODIFY TTL create_time + INTERVAL 10 SECOND;
涉及判断的字段必须是 Date 或者 Datetime 类型,推荐使用分区的日期字段。
能够使用的时间周期:
- SECOND
- MINUTE
- HOUR
- DAY
- WEEK
- MONTH
- QUARTER
- YEAR
4.5 ReplacingMergeTree
ReplacingMergeTree 是 MergeTree 的一个变种,它存储特性完全继承 MergeTree,
只是多了一个去重的功能。 尽管 MergeTree 可以设置主键,但是 primary key 其实没有
唯一约束的功能。如果你想处理掉重复的数据,可以借助这个 ReplacingMergeTree。
➢ 去重时机
数据的去重只会在合并的过程中出现 。合并会在未知的时间在后台进行,所以你无法预
先作出计划。有一些数据可能仍未被处理。
➢ 去重范围
如果表经过了分区,去重只会在分区内部进行去重,不能执行跨分区的去重 。
所以 ReplacingMergeTree 能力有限,
ReplacingMergeTree 适用于在后台清除重复
的数据以节省空间,但是它不保证没有重复的数据出现。
➢
案例演示
◼
创建表
ReplacingMergeTree() 填入的参数为版本字段,重复数据保留版本字段值最大的。
如果不填版本字段,默认按照插入顺序保留最后一条。
◼ 向表中插入数据
◼ 执行第一次查询
hadoop202 :) select * from t_order_rmt;
◼ 手动合并
OPTIMIZE TABLE t_order_rmt FINAL;
◼ 再执行一次查询
hadoop202 :) select * from t_order_rmt;
➢ 通过测试得到结论
◼
实际上是使用 order by 字段作为唯一键
◼
去重不能跨分区
◼
只有合并分区才会进行去重
◼
认定重复的数据保留,版本字段值最大的
◼
如果版本字段相同则按插入顺序保留最后一笔