目录
一、Log 系列引擎
Log 家族具有最小功能的轻量级引擎。当您需要快速写入许多小表(最多约 100w 行)并在以后整体读取它们时,该类型的引擎是最有效的。
1. TinyLog 引擎
- 将数据存储在磁盘上,没有索引,没有标记块
- 每列都存储在单独的压缩文件中
- 数据写入时追加写到文件末尾
- 该引擎没有并发控制,不允许同时读写
2. StrpeLog 引擎(数据分块列在一起)
3. Log 引擎(数据分块记录偏移量)
*.bin
存储每个字段的数据- mark.mrk 数据块标记
- 支持多线程处理
- 并发读写
二、MergeTree 系列表引擎
MergeTree 系列的表引擎支持主键索引、数据分区、数据副本和数据采样这些特性,同时也只有此系列的表引擎支持 ALTER 相关操作
特点:
- 存储按主键排序的数据
- 如果指定了分区键,则可以使用分区
- 数据复制支持:ReplacedMergeTree 表族提供数据复制。
- 数据采样支持
1. MergeTree
CREATE TABLE tb_merge_tree(
id Int8 ,
name String ,
ctime Date
)ENGINE=MergeTree()
PARTITION BY name --选填,如果不声明分区键,则 ClickHouse 会生成一个名为 all 的分区。
ORDER BY id --必填,默认情况下主键(PRIMARY KEY)与排序键相
PRIMARY id --选填,主键字段生成一级索引,主键允许存在重复数据
SAMPLE BY intHash32(id) --选填,用于声明数据以何种标准进行采样
SETTINGS index_granularity = 8192, --选填,索引的粒度
index_granularity_bytes = 0, --自适应间隔大小,根据每一批次写入数据的体量大小,动态划分间隔大小。0表示不启动自适应功能。
enable_mixed_granularity_parts = true, --选填,是否开启自适应索引间隔的功能,默认开启
merge_with_ttl_timeout = 10, --选填,数据TTL功能
storage_policy = 1; --选填,多路径存储策略
分区表-相同分区的表被合并到一起,过段时间以后 CK 内部自动的会删除合并前的多余的文件夹
MergeTree 存储结构
MergeTree 表引擎中的数据是拥有物理存储的,数据会按照分区目录的形式保存到磁盘上。
一张数据表的完整物理结构分为 3 个层级,依次是数据表目录、分区目录及各分区下具体的数据文件。
- checksums.txt:校验文件,使用二进制格式存储。用于快速校验文件的完整性和正确性。
- columns.txt:列信息文件,使用明文格式存储。用于保存次数据分区下的列字段信息。
- count.txt:计数文件,使用明文格式存储。用于记录当前数据分区目录下的总行数。
- primary.idx:一级索引文件,使用二进制格式存储,用于存放稀疏索引,一张 MergeTree 表只能声明一次稀疏索引(通过 order by 或 primary key)
- [column].bin:数据文件,使用压缩格式存储,默认为 LZ4 压缩格式,用于存储某一列的数据,每一个列字段都拥有独立的 .bin 数据文件,并以列字段名称命名(如 CounterID.bin)
- [column].mrk:列字段标记文件,使用二进制格式存储,标记文件中保存了 .bin 文件中数据的偏移量信息。标记文件与稀疏索引对齐,又与 .bin 文件一一对应,所以 MergeTree 通过标记文件建立了 primary.idx 稀疏索引与.bin数据文件之间的映射关系
- [column].mrk2:如果使用了自适应大小的索引间隔,则标记文件会以 .mrk2 命名。它的工作原理和作用与 .mrk 标记文件相同。
- partition.dat 与 minmax_[Column].idx:如果使用了分区键,则会额外生成 partition.dat 与 minmax 索引文件,它们均使用二进制格式存储。partition.dat 用于保存当前分区下分区表达式最终生成的值;而 minmax 索引用于记录当前分区下分区字段对应原始数据的最小和最大值。
新版本略有不同,如下:
2. ReplacingMergeTree
CREATE TABLE test_replacingMergeTree_version
(
id Int8 ,
name String ,
city String,
version Int8
)ENGINE = ReplacingMergeTree(version)
ORDER BY name
PARTITION BY city;
使用场景:适用于在后台清除重复的数据行以节省空间,但是它不保证没有重复的数据出现。
- (1)使用order by排序键作为判断重复数据的唯一依据
- (2)只有在合并分区的时候才会触发删除重复数据的逻辑,分区合并在未知时间的后台进行。
- (3)当分区合并时,同一分区内的重复数据会被删除;不同分区之间的重复数据不会被删除。
- (4)在进行数据去重时,因为分区内的数据已经基于ORBER BY进行了排序,所以能够找到那些相邻的重复数据。
- (5)数据去重策略有两种
如果没有设置 version 版本号,则保留同一组重复数据的最后一行
如果设置了 version 版本号,则保留同一组重复数据中版本取值最大的一行。
3. CollapsingMergeTree
CREATE TABLE tb_cps_merge_tree
(
user_id UInt64,
name String,
age UInt8,
sign Int8
)ENGINE = CollapsingMergeTree(sign)
ORDER BY user_id;
CollapsingMergeTree 是一种通过以增代删的思路,支持行级数据修改和删除的表引擎。
通过定义一个 sign 标记位字段,记录数据行的状态。如果 sign 标记为1,则表示这是一行有效的数据;如果 sign 标记为 -1,则表示这行数据需要被删除。当 CollapsingMergeTree 分区合并时,同一数据分区内,sign 标记为 1 和 -1 的一组数据会被抵消删除。
注意:CollapsingMergeTree 虽然解决了主键相同的数据即时删除的问题,但是状态持续变化且多线程并行写入情况下,状态行与取消行位置可能乱序,导致无法正常折叠。只有保证老的状态行在在取消行的上面, 新的状态行在取消行的下面! 但是多线程无法保证写的顺序!
4. VersionedCollapsingMergeTree
CREATE TABLE tb_vercps_merge_tree
(
uid UInt64,
name String,
age UInt8,
sign Int8,
version UInt8
)ENGINE = VersionedCollapsingMergeTree(sign, version)
ORDER BY uid;
INSERT INTO tb_vercps_merge_tree VALUES (1001, 'ADA', 18, -1, 1);
INSERT INTO tb_vercps_merge_tree VALUES (1001, 'ADA', 18, 1, 1),
(101, 'DAD', 19, 1, 2),
(101, 'DAD', 11, 1, 3);
OPTIMIZE TABLE tb_vercps_merge_tree;
SELECT * FROM tb_vercps_merge_tree;
解决 CollapsingMergeTree 乱序写入情况下无法正常删除(折叠)问题,在建表语句中新增了一列 version,用于在乱序情况下记录状态行与取消行的对应关系
主键(排序)相同,且 version 相同,sign 相反的行,在合并时会被删除。
5. SummingMergeTree
只需要查询汇总结果,不关心明细数据。并且数据的汇总条件是预先明确的(group by 条件明确,不会随意改变)
6. AggregatingMergeTree
通过定义 AggregateFunction(聚合函数,数据类型)决定针对哪些列字段计算。
写入时需要使用 -state 语法,查询时使用 -merge 语法。
三、外部存储引擎
1. HDFS 引擎
clickhouse 可以直接从 HDFS 中指定的目录下加载数据,自己不存储数据,仅仅读取数据
engine=HDFS('hdfs://linux01:8020/ck/test/*','csv')
-clickhouse支持的文件格式有CSV、TSV、JSON等
2. MySQL 引擎
engine=MYSQL('localhost:3306','test','test','root','123456')