核心知识与集群介绍(基于v21.11版本)
目录
1. 介绍
ClickHouse是一款由俄罗斯 Yandex 公司开发的用于联机分析(OLAP)的列式数据库管理系统(DBMS)。
常见的 OLAP 引擎: Hive、Spark SQL、Presto、Kylin、Impala、Druid、Clickhouse、Greeplum等。
2. 优缺点
特性:
- 真正的列式数据库管理系统
- 数据压缩
- 数据存储在磁盘.数据存储在磁盘可以降低成本,clickhouse 即使在普通磁盘上,也可以快速的查询出结果。
- 多核心并行处理
- 多服务器分布式处理.分布式表,可以利用多个服务器,并行执行查询。
- 支持 SQL
- 向量引擎
- 索引
- 适合在线查询
- 支持近似计算
- 自适应 join
- 支持数据副本机制.可以设置数据存储的备份,提高可用性。
- 角色控制
缺点:
- 没有完整的事务支持
- 不能高频、低延迟的修改或删除数据
- 不适合单行点查询
3. 表引擎
clickhouse 有多种表引擎,适用于不同的场景。建表语句如下:
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1],
name2 [type2] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|ALIAS expr2] [compression_codec] [TTL expr2],
...
) ENGINE = engine
3.1 Log
- 插入数据会锁表
- 不支持索引,也就是说范围查询效率不高
- 适用于临时数据,一次性写入的表,测试表
3.1.1 TinyLog
- 最简单的引擎
- 适合一次写入,只读的场景
- 数据量在 100w 以内
- 没有并发控制,同时读写会报错,并发写入,数据不可用
3.1.2 StripeLog
- 可以并发读,写入会阻塞读操作
3.1.3 Log
- 可以并发读,性能比 StripeLog 要好一些
- 因为使用 __marks.mrk 文件记录每个数据块的偏移,写入数据出现问题,表直接报废
3.2 Engine Families MergeTree
- 使用最多的表引擎
- 支持索引、分区
3.2.1 MergeTree
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1], -- MATERIALIZED 从别的列物化出来这一列, 用于减少查询时候的计算量
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2], -- ALIAS 不实际存储这一列, 在查询的时候执行
...
INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1, -- 二级索引
INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2,
...
PROJECTION projection_name_1 (SELECT <COLUMN LIST EXPR> [GROUP BY] [ORDER BY]), -- 实验性功能, part 级别的物化视图, 在查询的时候会自动使用
PROJECTION projection_name_2 (SELECT <COLUMN LIST EXPR> [GROUP BY] [ORDER BY])
) ENGINE = MergeTree()
ORDER BY expr -- 排序字段
[PARTITION BY expr] -- 分区
[PRIMARY KEY expr] -- 主键, 默认和 order by 一致, 一般情况下不设置, 跟 order by 保持一致
[SAMPLE BY expr] -- 抽样, 必须是主键或者排序字段包含的字段, 必须是 UInt 类型字段
[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, ...]
使用示例:
-- 示例1
CREATE TABLE test.label_number_local
(
`tag_code` String,
`user_id` UInt64 COMMENT '用户 id',
`value` Float64 COMMENT '标签值'
)
ENGINE = MergeTree
PARTITION BY tag_code
ORDER BY tag_code
-- 示例2, TTL
CREATE TABLE test.dw_domestic_hotel_monitor_crm_realtime
(
`dt` String COMMENT '时间分区',
`type` String COMMENT '类型',
`hour` String COMMENT '小时',
`hotel_seq` String COMMENT 'hotel_seq',
`device_id` String COMMENT '设备id',
`platform` String COMMENT '客户端',
......
)
ENGINE = MergeTree()
PARTITION BY (dt,
type)
ORDER BY (dt,
hour,
type,
......)
-- 删除 dt+2day <= today(now()) and type!='order' 的数据, 即保留最近两天(包括当天)的数据
TTL parseDateTimeBestEffort(dt) + toIntervalDay(2) WHERE type != 'order'
-- 示例3, sample
CREATE TABLE test.clicks
(
`CounterID` UInt64,
`EventDate` DATE,
`UserID` UInt64
)
ENGINE = MergeTree()
ORDER BY (CounterID, intHash32(UserID))
SAMPLE BY intHash32(UserID)
-- 查询, 按 intHash32(UserID) 采样, 伪随机, 相同采样率每次查询结果一致
select * from test.clicks sample 0.2
3.2.2 ReplacingMergeTree
会自动删除具有相同 order by 字段值的重复数据。但是他只会在后台合并分区文件的时候删除,所以不可靠。适用于清除重复数据节省空间,但不保证没有重复数据。
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = ReplacingMergeTree([ver]) -- 带有版本号的列, 支持的数据类型 UInt*, Date, DateTime, DateTime64
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
3.2.3 SummingMergeT