clickhouse21.7.11.3 表引擎-MergeTree介绍

说明

是最强大的 ClickHouse 表引擎

该系列中的引擎设计用于将大量数据插入表中

国内文档 链接

主要特点:

  • 基于分区键(partitioning key)的数据分区分块存储
  • 数据索引排序(基于primary key和order by)
  • 支持数据复制(带Replicated前缀的表引擎)
  • 支持数据抽样

缺点

主键没有唯一约束,即:允许插入主键相同的数据

这里如果需要去重,可以使用 ReplacingMergeTree引擎

创建表

语法

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
    ...
    INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
    INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
ORDER BY expr
[PARTITION BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[TTL expr
    [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx' [, ...] ]
    [WHERE conditions]
    [GROUP BY key_expr [SET v1 = aggr_func(v1) [, v2 = aggr_func(v2) ...]] ] ]
[SETTINGS name=value, ...]

解释

  • ENGINE— 引擎的名称和参数

  • ORDER BY— 排序字段
    列名或任意表达式。例:ORDER BY (CounterID, EventDate)
    如果没有定义主键,则使用排序字段作为主键。因为排序字段的值可以重复,所以 主键 也可以重复

  • PARTITION BY— 分区字段,查询时避免全表扫描。可选
    如果某列是 Date 类型(年月日),要按月分区,需要使用表达式格式化,如:toYYYYMM(date_column),该列的结果是 YYYYMM 格式

  • PRIMARY KEY— 可选。默认情况下,主键与排序字段相同(所以 不具备唯一性),当与分区字段不同时,可指定。更多解释见 链接

例子

create table t_student_mt
(
    sid UInt32,
    name String,
    age int,
    `height` UInt32,
    create_time Datetime
)
engine = MergeTree
partition by toYYYYMMDD(create_time)
PRIMARY KEY (sid)
order by (sid,age)

解释:

  • 根据 create_time 的 年月日分区
  • 注解时 sid,注意:可以不唯一
  • 按照 sid、age 排序

插入数据

insert into t_student_mt values 
(1,'lucy',22,170,'2022-01-02 09:30:00'),
(4,'lili',22,171,'2022-01-02 09:50:00'),
(4,'张三',21,171,'2022-01-02 09:50:00'),
(2,'韩梅梅',19,165,'2022-01-01 09:30:00'),
(2,'李雷',20,182,'2022-01-01 09:30:00');

注意: 李雷、韩梅梅 的主键时相同的,也能够插入成功

clickhouse客户端查询

打开客户端:

clickhouse-client -m

查询:

select * from t_student_mt

执行结果如下(分区与分区之间是乱序,分区内是有序的):

Query id: dfd1f18c-bd90-4f48-9bea-c60e34ae396c

┌─sid─┬─name───┬─age─┬─heigth─┬─────────create_time─┐
│   2 │ 韩梅梅 │  19 │    165 │ 2022-01-01 09:30:00 │
│   2 │ 李雷   │  20 │    182 │ 2022-01-01 09:30:00 │
└─────┴────────┴─────┴────────┴─────────────────────┘
┌─sid─┬─name─┬─age─┬─heigth─┬─────────create_time─┐
│   1 │ lucy │  22 │    170 │ 2022-01-02 09:30:00 │
│   4 │ 张三 │  21 │    171 │ 2022-01-02 09:50:00 │
│   4 │ lili │  22 │    171 │ 2022-01-02 09:50:00 │
└─────┴──────┴─────┴────────┴─────────────────────┘

4 rows in set. Elapsed: 0.003 sec.

问题:为什么分成2个部分

是因为根据 create_time 的 年月日 分区

注意:在 DBeaver 查询时,看不到该效果

问题:为什么主键可以重复

在 clickhouse 中,主键可以重复

问题:为什么不按照 sid、age 排序

因为是分区内排序,根据 create_time 的 年月日 分为2个区:

  1. 第一个区是 2022-01-01,该区内,按照 sid 排序;当 sid相同时,按照 age 排序
  2. 第二个区是 2022-01-02,该区内,按照 sid 排序;当 sid相同时,按照 age 排序

原文出处:/show_1IX3OmqTGxbg.html