ClickHouse 的核心表引擎是其高性能分析能力的基石。与其他数据库“一种引擎走天下”不同,ClickHouse 提供了多种表引擎,每种针对不同场景优化。其中,MergeTree 系列是绝对的核心,撑起了 90% 以上的生产使用场景。
本篇将全面、深入地详解 ClickHouse 的核心表引擎,重点聚焦 MergeTree 及其家族,并对比其他重要引擎,帮助你理解“用什么、为什么用、怎么用”。
🏗️ 一、ClickHouse 表引擎分类概览
ClickHouse 的表引擎可分为五大类:
| 类别 | 代表引擎 | 用途 |
|---|---|---|
| 1. 核心:MergeTree 系列 | MergeTree, ReplicatedMergeTree 等 | OLAP 主力引擎,支持高效写入与查询 ✅(本文重点) |
| 2. 集成引擎 | Kafka, MySQL, S3, HDFS | 与外部系统交互 |
| 3. 特殊用途引擎 | Dictionary, Memory, Log, Null | 缓存、临时表、测试等 |
| 4. 联邦查询引擎 | Distributed, Join, Set | 分布式查询、集合操作 |
| 5. 虚拟表引擎 | View, MaterializedView | 查询封装与物化结果 |
🔥 本文重点:第一类 —— MergeTree 系列表引擎
🔥 二、MergeTree:ClickHouse 的“心脏引擎”
✅ 为什么它是核心?
- 支持海量数据的高效写入与查询
- 数据按主键排序存储,支持稀疏索引和分区裁剪
- 后台自动合并数据片段(Part),优化查询性能
- 支持 TTL、采样、副本等高级功能
- 是所有高级引擎(如
ReplacingMergeTree)的基础
✅ 基本语法
CREATE TABLE user_log (
user_id UInt32,
event_date Date,
action String,
duration UInt32
) ENGINE = MergeTree()
ORDER BY (event_date, user_id)
PARTITION BY toYYYYMM(event_date);
✅ 核心特性详解
| 特性 | 说明 |
|---|---|
| 列式存储 | 每列独立存储,聚合查询只读所需列 |
| 数据排序(ORDER BY) | 数据物理排序,利于压缩和索引跳过 |
| 稀疏索引(Sparse Index) | 每 8192 行建一个索引标记,快速定位数据块 |
| 数据分区(Partitioning) | 按日期等字段分区,支持快速删除和查询裁剪 |
| 数据合并(Merge) | 后台异步合并小 Parts 成大 Parts,提升效率 |
| 批量写入优化 | 追加写,不支持高频单行更新 |
⚠️ 注意:
MergeTree不支持事务、UPDATE、DELETE(逻辑上可通过变种实现)
🧬 三、MergeTree 家族:六大核心变种
MergeTree 有多个“子引擎”,在基础功能上扩展特定能力。
1. ReplacingMergeTree —— 自动去重
✅ 用途
自动合并主键相同的行,保留最新版本(需配合 GROUP BY 或 FINAL 查询)。
✅ 适用场景
- 数据可能重复写入(如重试机制)
- 需要“最终一致性”的更新(如用户状态变更)
✅ 示例
CREATE TABLE user_state (
user_id UInt32,
status String,
update_time DateTime
) ENGINE = ReplacingMergeTree(update_time) -- 指定版本列(可选)
ORDER BY user_id;
🔁 合并时会保留
update_time最大的那条记录。
✅ 查询去重
SELECT * FROM user_state FINAL; -- 强制合并查询(性能差)
-- 或
SELECT user_id, argMax(status, update_time) FROM user_state GROUP BY user_id; -- 推荐
2. SummingMergeTree —— 自动聚合数值字段
✅ 用途
自动合并主键相同的行,对数值列求和。
✅ 适用场景
- 预聚合统计(如订单金额、访问次数)
- 减少数据量,提升查询速度
✅ 示例
CREATE TABLE order_stats (
date Date,
category_id UInt32,
orders_cnt UInt32,
total_amount UInt64
) ENGINE = SummingMergeTree()
ORDER BY (date, category_id)
-- 可指定聚合列:SummingMergeTree(orders_cnt, total_amount)
🔁 合并后,相同
(date, category_id)的记录会被合并,orders_cnt和total_amount自动求和。
✅ 注意
- 非聚合列(如
category_name)可能丢失或取任意值 - 适合“只关心总数”的场景
3. AggregatingMergeTree —— 预聚合复杂指标
✅ 用途
存储聚合函数的状态(如 Sum, Count, Uniq, Merge),用于物化视图预计算。
✅ 适用场景
- 构建物化视图,加速
GROUP BY查询 - 实现“秒级响应”的复杂聚合
✅ 示例
CREATE TABLE user_aggregates (
date Date,
city String,
visit_count SimpleAggregateFunction(sum, UInt64),
unique_users AggregateFunction(uniq, UInt32)
) ENGINE = AggregatingMergeTree()
ORDER BY (date, city);
✅ 插入需使用聚合函数
INSERT INTO user_aggregates
SELECT
today(),
'Beijing',
sum(1),
uniqState(user_id)
FROM user_log
WHERE city = 'Beijing';
✅ 查询时使用 Merge
SELECT
date,
city,
sum(visit_count),
uniqMerge(unique_users)
FROM user_aggregates
GROUP BY date, city;
💡 常用于:
物化视图 + AggregatingMergeTree构建实时聚合层。
4. CollapsingMergeTree —— 折叠变更记录
✅ 用途
支持“状态变更”记录,通过 sign 列标记行是“插入”还是“删除”。
✅ 适用场景
- 需要记录“增删改”操作流
- 类似 CDC(变更数据捕获)场景
✅ 示例
CREATE TABLE feed_log (
post_id UInt32,
user_id UInt32,
is_liked UInt8,
sign Int8 -- +1 表示新增,-1 表示取消
) ENGINE = CollapsingMergeTree(sign)
ORDER BY (post_id, user_id);
🔁 合并后,
+1和-1会相互抵消,最终保留有效状态。
✅ 查询需用 FINAL 或 GROUP BY
SELECT post_id, sum(is_liked * sign) FROM feed_log GROUP BY post_id;
5. VersionedCollapsingMergeTree —— 更智能的折叠引擎
✅ 升级版 CollapsingMergeTree
- 使用
(version, sign)两列控制合并逻辑 - 更适合 Kafka 等带版本号的消息流
✅ 适用场景
- 消费带版本号的 CDC 数据(如 Debezium)
- 确保变更顺序正确
6. ReplicatedMergeTree —— 支持数据复制
✅ 用途
在 MergeTree 基础上增加多副本支持,实现高可用。
✅ 语法
CREATE TABLE replicated_log (
...
) ENGINE = ReplicatedMergeTree(
'/clickhouse/tables/{shard}/replicated_log', -- ZooKeeper 路径
'{replica}' -- 副本标识
)
ORDER BY (event_date, user_id);
✅ 依赖
- ZooKeeper 或 ClickHouse Keeper(v21+ 内置)
- 用于协调副本间的数据同步、选举、合并
✅ 优势
- 数据不丢失,节点宕机可自动恢复
- 支持读写负载均衡
- 是构建分布式 ClickHouse 集群的基础
📊 四、核心引擎对比表
| 引擎 | 去重 | 聚合 | 复制 | 适用场景 |
|---|---|---|---|---|
MergeTree | ❌ | ❌ | ❌ | 通用 OLAP 表 |
ReplacingMergeTree | ✅(主键) | ❌ | ⚠️(需复制版) | 去重、状态更新 |
SummingMergeTree | ❌ | ✅(数值求和) | ⚠️ | 预聚合统计 |
AggregatingMergeTree | ❌ | ✅(任意聚合) | ⚠️ | 物化视图、实时聚合 |
CollapsingMergeTree | ✅(正负抵消) | ❌ | ⚠️ | 状态变更流 |
ReplicatedMergeTree | ❌ | ❌ | ✅ | 高可用、多副本 |
📌 注:所有
*MergeTree都有对应的Replicated*版本,如ReplicatedReplacingMergeTree。
🏁 五、如何选择核心表引擎?
| 你的需求 | 推荐引擎 |
|---|---|
| 通用分析表,写多读多 | MergeTree |
| 数据可能重复,需去重 | ReplacingMergeTree |
| 统计指标,只关心总数 | SummingMergeTree |
| 复杂聚合(如 UV、PV) | AggregatingMergeTree + 物化视图 |
| 用户行为流,状态变更 | CollapsingMergeTree |
| 高可用、防止单点故障 | ReplicatedMergeTree |
| 实时数仓 + Kafka | ReplicatedReplacingMergeTree 或 VersionedCollapsingMergeTree |
✅ 六、最佳实践建议
- 优先使用
MergeTree系列,它是为 OLAP 量身打造的。 - 合理设计
ORDER BY:将最常用于过滤的字段放前面。 - 按日期分区:
PARTITION BY toYYYYMM(event_date),便于管理。 - 避免高频小批量写入:建议每批 > 1000 行。
- 慎用
FINAL:性能差,推荐用GROUP BY替代。 - 生产环境必用复制:
ReplicatedMergeTree+ ZooKeeper/ClickHouse Keeper。
🎯 总结:MergeTree 为什么是核心?
MergeTree 是 ClickHouse 的“操作系统内核”:
- 它定义了数据如何存储(列式 + 排序)
- 如何索引(稀疏索引)
- 如何写入(追加 + 合并)
- 如何扩展(分区、TTL、副本)
所有其他引擎都是在这个基础上的“增强”或“专用化”。
📌 记住一句话:
“不会用 MergeTree,就不算真正会用 ClickHouse。”

2038

被折叠的 条评论
为什么被折叠?



