本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 chaodev 即可关注。
推荐阅读:
《手摸手带你学ClickHouse》之安装部署
《手摸手带你学ClickHouse》之访问接口
《手摸手带你学ClickHouse》之导入导出数据
前面的文章详细介绍了ClickHouse单机的安装部署、ClickHouse监听端口、访问接口、设置允许其他ip访问、可视化的客户端以及数据的导入导出。本文主要内容为ClickHouse数据存储功能的核心,也就是MergeTree系列的表引擎。
1、MergeTree系列表引擎
MergeTree系列的表引擎是ClickHouse数据存储功能的核心。它们提供了用于弹性和高性能数据检索的大多数功能:列存储,自定义分区,稀疏的主索引,辅助数据跳过索引等。基本MergeTree表引擎可以被认为是单节点ClickHouse实例的默认表引擎,因为它在各种用例中通用且实用。
除了基础表引擎MergeTree
之外,常用的表引擎还有ReplacingMergeTree、SummingMergeTree、AggregatingMergeTree、CollapsingMergeTree和VersionedCollapsingMergeTree
。
每一种合并树的变种,在继承了基础MergeTree的能力之后,又增加了独有的特性。其名称中的“合并”二字奠定了所有类型MergeTree的基因,它们的所有特殊逻辑,都是在触发合并的过程中被激活的。
主要特点:
- 存储按主键排序的数据。
- 如果指定了分区键则可以使用分区。
表引擎(即表的类型)决定了:
- 数据的存储方式和位置,写到哪里以及从哪里读取数据.
- 支持哪些查询以及如何支持。
- 并发数据访问。
- 索引的使用(如果存在)。
- 是否可以执行多线程请求。
- 数据复制参数。
后续内容将针对常用表引擎的使用进行详细讲解,下面我们先看基础表引擎MergeTree。
2、MergeTree表引擎
MergeTree表引擎是ClickHouse的基础表引擎,下面进行详细介绍。
2.1 创建表
create table tb_merge_tree(
uid UInt8,
name String,
birthday Date,
city String ,
gender String
)engine = MergeTree()
primary key uid
order by (uid ,birthday);
注:如果指定了主键,排序字段第一个字段必须是主键。如果没指定,则排序字段就是主键字段。
插入数据:
insert into tb_merge_tree values(1,'zhangsan',toDate(now()),'BJ','M'),
(2,'lisi',toDate(now()),'SH','M'),
(3,'wanger ','1996-01-05','BJ','M');
2.2 底层数据结构
接下来我们看下底层是怎么组织数据的,进入到数据存储目录
因为这个表没有建立分区,所以数据都在all这个里面
.bin的就是字段值,.mrk2是标记,标记数据的位置,checksums.txt是做数据校验的,count.txt记录当前数据的条数。
2.3 主键没有唯一性要求
在ClickHouse中主键可重复,没有唯一性要求,只是用来建立索引,如下,我们可以再插入一次相同数据
2.4 合并树
这里需要注意的是,如果再次插入数据,这里还会再产生一个all文件,因为是不同批次插入的数据,如下
可以看到数据也是分两块来存储
如果需要合并树,执行如下命令
optimize table tb_merge_tree;
或者
optimize table tb_merge_tree final;
加final的作用是如果有多个会同时一次性合并。
可以看到数据已合并到all_1_3_2中,过一段时间另外两个将会自动删除,如下
2.5 索引粒度
上面我们创建表的时候没有指定索引粒度,因为默认就是8192,查看一下建表语句
SETTINGS index_granularity = 8192
设置为8192就代表每隔8192行数据建一个索引,这样就大大节省了索引标记占用的空间,所以primary.idx内的索引数据常驻内存,取用速度就会很快。
2.6 分区
要使用分区需要在建表的时候指定partition by 字段名,如下
create table tb_merge_tree2(
uid UInt8,
name String,
birthday Date,
city String
)engine = MergeTree()
partition by birthday
primary key uid
order by (uid ,birthday);
这里指定了生日为分区,也就是日期相同的会在同一个分区,插入数据
insert into tb_merge_tree2 values(1,'zhangsan',toDate(now()),'BJ'),
(2,'lisi',toDate(now()),'KM'),
(3,'wanger ','1996-01-01','BJ'),
(3,'mazi ','1996-01-01','KM'),
(3,'mazi ','2000-11-11','KM');
可以看到,这里按日期建立了三个分区存储,在system的parts表中也可以查询到分区信息,如下
select table,name,partition from system.parts where table='tb_merge_tree2';
后续将继续更新该系列,大佬超手摸手带你学ClickHouse,敬请关注!!!
觉得有帮助点个赞吧!!!
原创不易,转载请注明出处。
微信扫一扫下方二维码即可关注我的公众号