以下是 ClickHouse 核心概念的全面详解,帮助你从架构设计到数据组织方式,深入理解 ClickHouse 的工作原理。这些概念是掌握 ClickHouse 使用、优化和调优的基础。
🔍 ClickHouse 核心概念详解
ClickHouse 是一个为 高性能 OLAP(联机分析处理) 而生的列式数据库,其设计围绕“快读、大吞吐、高聚合”展开。要真正用好它,必须理解以下六大核心概念:
1. 数据库与表(Database & Table)
✅ 基本结构
- Database:逻辑上的命名空间,用于组织表(类似 MySQL)。
- Table:数据存储的基本单位,必须属于某个数据库。
CREATE DATABASE IF NOT EXISTS analytics;
CREATE TABLE analytics.user_log (
user_id UInt32,
event_date Date,
action String,
duration UInt32
) ENGINE = MergeTree()
ORDER BY (event_date, user_id);
⚠️ 注意:ClickHouse 的表必须指定 表引擎(Engine),这是它与传统数据库的最大区别之一。
2. 表引擎(Table Engine)—— ClickHouse 的灵魂
表引擎决定了数据如何存储、压缩、索引、写入和查询。它是 ClickHouse 性能差异的核心。
🌟 最重要的引擎系列:MergeTree
| 引擎 | 用途 |
|---|---|
MergeTree | 基础引擎,支持高效插入和范围查询 |
ReplacingMergeTree | 自动去重(按主键) |
SummingMergeTree | 自动合并相同主键的数值字段(如 sum) |
AggregatingMergeTree | 预聚合(适合物化视图) |
CollapsingMergeTree / VersionedCollapsingMergeTree | 支持“状态变更”记录(如更新、删除) |
🔁 所有
MergeTree引擎的数据会异步合并(Merge),以优化存储和查询性能。
其他常用引擎
| 引擎 | 说明 |
|---|---|
Distributed | 分布式表,跨节点查询路由 |
Kafka | 直接消费 Kafka 消息流 |
MySQL | 外部表引擎,可实时读取 MySQL 表 |
TinyLog / Log | 小数据测试用,不推荐生产 |
✅ 生产环境绝大多数使用
MergeTree及其变种。
3. 列(Column)与数据类型
✅ 列式存储的本质
- 每一列独立存储在磁盘上。
- 查询时只读取需要的列 → 减少 I/O。
常见数据类型
| 类型 | 说明 |
|---|---|
UInt8/16/32/64 | 无符号整数(推荐代替 Int,节省空间) |
Int8/16/32/64 | 有符号整数 |
Float32/64 | 浮点数 |
String | 变长字符串(无长度限制) |
FixedString(N) | 固定长度字符串 |
Date | 日期(YYYY-MM-DD) |
DateTime | 日期时间(支持时区) |
Enum8/16 | 枚举类型(节省空间) |
Array(T) | 数组类型 |
Nullable(T) | 允许为空的类型(慎用,影响性能) |
💡 推荐原则:用最小的类型满足需求,例如用户 ID 用
UInt32而非String。
4. 主键与排序键(Primary Key & ORDER BY)
✅ ORDER BY 是关键!
在 ClickHouse 中:
ORDER BY定义了数据的物理排序顺序。- 数据按此顺序存储在磁盘上。
CREATE TABLE logs (
...
) ENGINE = MergeTree()
ORDER BY (event_date, city, user_id);
✅ 数据排序后,相同值连续存储,利于压缩和快速跳过。
✅ 主键(Primary Key)
- 默认等于
ORDER BY的前缀。 - 用于构建 稀疏索引(Sparse Index)。
PRIMARY KEY (event_date, city) -- 可显式指定
⚠️ 注意:
- 主键不强制唯一性(不像 MySQL)。
- 不支持
UNIQUE约束(除非用ReplacingMergeTree实现去重)。
5. 稀疏索引(Sparse Index)—— 快速定位的秘诀
✅ 是什么?
- 不是每行建索引,而是每隔 8192 行(默认)建立一个“标记”(mark),记录该位置的主键值。
- 索引体积小,内存占用低。
✅ 如何工作?
查询:
SELECT * FROM logs WHERE event_date = '2024-04-01'
- 稀疏索引定位到
event_date = '2024-04-01'的数据块范围; - 只扫描这些数据块,跳过其他所有块;
- 结合列式存储,只读取相关列。
🚀 效果:极大减少扫描数据量,提升查询速度。
⚠️ 注意:条件列必须在
ORDER BY中才能有效利用稀疏索引!
6. 数据分区(Partitioning)
✅ 什么是分区?
- 将数据按某个规则(如日期)拆分成多个目录(物理隔离)。
- 常见分区键:
toYYYYMM(event_date)、event_date等。
CREATE TABLE logs (
...
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id);
✅ 分区的好处
| 优势 | 说明 |
|---|---|
| ✅ 快速删除 | ALTER TABLE logs DROP PARTITION 202403 瞬间删除整月数据 |
| ✅ 查询裁剪 | 查询时自动跳过无关分区,减少扫描 |
| ✅ 并行处理 | 每个分区可独立合并、备份 |
⚠️ 注意:
- 分区不宜过多(建议几千以内),否则元数据开销大。
- 分区键通常是日期或地区等粗粒度字段。
🧩 附加核心概念
7. 数据写入与合并机制(Merge)
- ClickHouse 写入是 追加式(Append-only),不支持原地更新。
- 每次插入生成一个“数据部分(Data Part)”。
- 后台异步合并(Merge)小 Parts 成大 Parts,提升查询效率。
- 合并过程由
MergeTree引擎自动管理。
🔄 合并策略可配置(如
Leveled、TTL合并等)。
8. 分布式架构:分片与复制(Sharding & Replication)
✅ 分片(Sharding)
- 数据水平拆分到多个节点。
- 使用
Distributed表引擎实现透明查询。
CREATE TABLE distributed_log AS user_log
ENGINE = Distributed(cluster_name, default, user_log, rand());
✅ 复制(Replication)
- 使用
ReplicatedMergeTree引擎实现多副本。 - 数据通过 ZooKeeper 协调同步,保证高可用。
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/user_log', '{replica}')
ORDER BY (event_date, user_id)
🌐 适用于大规模集群部署。
9. SQL 支持与限制
✅ 支持的:
- 标准 SQL:
SELECT,GROUP BY,HAVING,ORDER BY,JOIN, 子查询 - 窗口函数(v20+)
- 数组、嵌套结构、JSON 解析(
JSONExtract)
❌ 不支持的:
- 事务(ACID)
- 行级
UPDATE/DELETE(虽支持但性能差) - 外键约束
- 高并发点查(非强项)
📊 总结:ClickHouse 核心概念图谱
+------------------+
| Database |
+--------+---------+
|
+--------v---------+
| Table |
| Engine: MergeTree |
+--------+---------+
|
+--------------+------------------+
| | |
+----v----+ +-----v------+ +-------v--------+
| Columns | | ORDER BY | | Partitioning |
| (列式) | | (排序键) | | (按月/天分区) |
+----+----+ +-----+------+ +-------+--------+
| | |
| +-----v------+ |
| | Sparse |<----------+
+------->| Index | 利用排序 + 分区 跳过数据
| (稀疏索引) |
+-----+------+
|
+-----v------+
| Data Parts |
| (数据片段) |
+-----+------+
|
+-----v------+
| Merge |
| (后台合并) |
+------------+
✅ 使用建议(最佳实践)
| 项目 | 推荐做法 |
|---|---|
| 表引擎 | 优先使用 MergeTree 或 ReplicatedMergeTree |
| 排序键 | 将最常用于过滤的字段放在 ORDER BY 前面 |
| 分区 | 按日期分区(如 toYYYYMM(event_date)) |
| 主键 | 与 ORDER BY 一致或为其前缀 |
| 写入 | 批量插入(每次 > 1000 行),避免高频小写 |
| 更新 | 用 ReplacingMergeTree + GROUP BY 实现逻辑更新 |
| 查询 | 尽量使用分区裁剪 + 主键过滤,避免全表扫描 |
🎯 总结一句话
ClickHouse 的核心在于:列式存储 + MergeTree 引擎 + 排序 + 稀疏索引 + 分区 + 合并机制,共同构建了一个为“海量数据高速分析”而生的数据库系统。
掌握这些概念,你就掌握了 ClickHouse 的“操作系统”,可以开始构建高性能数据分析平台了!
989

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



