建表
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name(
name1 type [DEFAULT|MATERIALIZED|ALIAS expr],
name2 type [DEFAULT|MATERIALIZED|ALIAS expr],
......
) ENGINE = MergeTree()
[PARTITION BY expr]
ORDER BY expr
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name1=value1, name2=value2, ......]
说明:
- 1) PARTITON BY:选填,表示分区键,用于指定表数据以何种标准进行分区。分区键既可以是单个字段、也可以通过元组的形式指定多个字段,同时也支持使用列表达式。如果不支持分区键,那么 ClickHouse 会生成一个名称为 all 的分区,合理地使用分区可以有效的减少查询时数据量。最常见的莫过于按照时间分区了,数据量非常大的时候可以按照天来分区,一天一个分区,这样查找某一天的数据时直接从指定分区中查找即可。**
- 2)ORDER BY:必填,表示排序键,用于指定在一个分区内,数据以何种标准进行排序。排序键既可以是单个字段,例如 ORDER BY CounterID,也可以是通过元组声明的多个字段,例如 ORDER BY (CounterID, EventDate)。如果是多个字段,那么会先按照第一个字段排序,如果第一个字段中有相同的值,那么再按照第二个字段排序,依次类推。总之在每个分区内,数据是按照分区键排好序的,但多个分区之间就没有这种关系了。**
- 3)PRIMARY KEY:选填,表示主键,声明之后会依次按照主键字段生成一级索引,用于加速表查询。如果不指定,那么主键默认和排序键相同,所以通常直接使用 ORDER BY 代为指定主键,无须使用 PRIMARY KEY 声明。所以一般情况下,在每个分区内,数据与一级索引以相同的规则升序排列(因为数据是按照排序键排列的,而一级索引也是按排序键、也就是主键进行排列的)。和其它关系型数据库不同,MergeTree 允许主键有重复数据(可以通过 ReplacingMergeTree 实现去重)。**
- 4)SAMPLE KEY:选填,抽样表达式。用于声明数据以何种标准进行采样,**
- 5)settings 额外参数 选填 例如SETTINGS index_granularity=8192, min_compress_block_size=6536
MergeTree数据结构
-
数据文件
table |----partition_1 //分区目录 | |---checksums.txt //校验文件,保存了余下各类文件(primary.txt、count.txt 等等)的 size 大小以及哈希值,用于快速校验文件的完整性和正确性 | |---columns.txt // 列信息文件,使用明文格式存储列字段信息 | |---count.txt // 计数文件,使用明文格式存储当前分区下的数据总数 | |---primary.idx // 一级索引文件,使用二进制格式存储,用于存储稀疏索引,(通过 ORDER BY 或 PRIMARY KEY)。借助稀疏索引,在查询数据时能够排除主键条件范围之外的数据文件,从而有效减少数据扫描范围,加速查询速度 | |---data.bin // 数据文件 。在老版本中每一个列字段都有自己独立的 .bin 数据文件,并以列字段命名,但是在新版本中只有一个 data.bin,也就是合并在一起了;但是我看按很多文章中都是独立的,不影响理解; | |---data.mrk // 标记文件,,使用二进制格式存储,标记文件中保存了 data.bin 文件中数据的偏移量信息,并且标记文件与稀疏索引对齐,因此 MergeTree 通过标记文件建立了稀疏索引(primary.idx)与数据文件(data.bin)之间的映射关系 | |---data.mrk3// 如果使用了自适应大小的索引间隔则使用mrk3 | |---partition.dat // 如果使用了分区键,例如上面的 PARTITION BY toYYYYMM(JoinTime),则会额外生成 partition.dat 与 minmax_JoinTime.idx 索引文件,它们均使用二进制格式存储。partition.dat 用于保存当前分区下分区表达式最终生成的值,而 minmax_[Column].idx 则负责记录当前分区下分区字段对应原始数据的最小值和最大值。 | |---minmax_[Column].idx | |---skp_idx_[IndexName].idx // 如果在建表语句中指定了二级索引(跳数索引),则会额外生成相应的二级索引文件与标记文件,它们同样使用二进制存储; | |---skp_idx_[IndexName].mrk3 | |----partition_2 |... |----partition_n
-
主键索引
-
为什么不是B(+)-树,1):额外的磁盘和内存开销, 2)向表中添加新行和向索引中添加条目时更高的插入成本(有时还需要重新平衡B-Tree)。; 好处是快速定位主键
-
clickhouse中不是为每一行创建索引,而是为一组数据行(称为颗粒(granule))构建一个索引条目。与直接定位单个行(如基于B-Tree的索引)不同,稀疏主索引允许它快速(通过对索引项进行二分查找)识别可能匹配查询的行组。
-
颗粒对应主索引
-
-
跳数索引,
- 1.minmax一种类型简单的说就是只保存块内的最大值和最小值;
- 2.set 类型,指定块的最大值,有点类似于基数排序里面的基数
- 3.bloomfilter
Reference: clickhouse.com/docs/zh/gui…