ClickHouse 中的主键,和其他数据库不太一样, 它只提供了数据的一级索引,但是却


不是唯一约束 。这就意味着是可以存在相同 primary key 的数据的。


主键的设定主要依据是查询语句中的 where 条件


根据条件通过对主键进行某种形式的二分查找,能够定位到对应的 index granularity,



避免了全表扫描。



index granularity:



直接翻译的话就是索引粒度,指在稀疏索引中两个相邻索引对



应数据的间隔。ClickHouse 中的 MergeTree 默认是 8192。官方不建议修改这个值,除非



该列存在大量重复值,比如在一个分区中几万行才有一个不同数据。




clihouse需要创建索引吗 clickhouse 唯一索引_clihouse需要创建索引吗


 


稀疏索引的好处就是可以用很少的索引数据,定位更多的数据,代价就是只能定位到索


引粒度的第一行,然后再进行进行一点扫描。


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)创建测试表


clihouse需要创建索引吗 clickhouse 唯一索引_主键_02


其中 GRANULARITY N 是设定二级索引对于一级索引粒度的粒度。


(3)插入数据


clihouse需要创建索引吗 clickhouse 唯一索引_大数据_03

 

clihouse需要创建索引吗 clickhouse 唯一索引_字段_04

(4)对比效果


那么在使用下面语句进行测试,可以看出二级索引能够为非主键字段的查询发挥作用。


clihouse需要创建索引吗 clickhouse 唯一索引_大数据_05


 


4.4.5 数据 TTL


TTL 即 Time To Live,MergeTree 提供了可以管理数据或者列的生命周期的功能。


(1)列级别 TTL


创建测试表


clihouse需要创建索引吗 clickhouse 唯一索引_主键_06


插入数据(注意:根据实际时间改变)

clihouse需要创建索引吗 clickhouse 唯一索引_数据_07

➢ 手动合并,查看效果 到期后,指定的字段数据归 0

clihouse需要创建索引吗 clickhouse 唯一索引_数据_08

 


(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 适用于在后台清除重复


的数据以节省空间,但是它不保证没有重复的数据出现。



案例演示



创建表


clihouse需要创建索引吗 clickhouse 唯一索引_大数据_09


 


ReplacingMergeTree() 填入的参数为版本字段,重复数据保留版本字段值最大的。


如果不填版本字段,默认按照插入顺序保留最后一条。


向表中插入数据


clihouse需要创建索引吗 clickhouse 唯一索引_数据_10


 


执行第一次查询


hadoop202 :) select * from t_order_rmt;


clihouse需要创建索引吗 clickhouse 唯一索引_clihouse需要创建索引吗_11


 


手动合并


OPTIMIZE TABLE t_order_rmt FINAL;


再执行一次查询


hadoop202 :) select * from t_order_rmt;


clihouse需要创建索引吗 clickhouse 唯一索引_数据_12


 


通过测试得到结论



实际上是使用 order by 字段作为唯一键



去重不能跨分区



只有合并分区才会进行去重



认定重复的数据保留,版本字段值最大的



如果版本字段相同则按插入顺序保留最后一笔