ClickHouse的Partition和Part概念

一、ClickHouse 表的数据存储层次

可以用一句话总结:

数据表 → 分区(Partition) → 数据分片(Part) → 数据文件。

也就是说:

一个表有多个「分区」,

每个分区下有若干个「part」,

每个 part 由多种文件组成(列文件、索引文件、校验、元数据等)。

二、分区(Partition)

🧩 1️⃣ 定义

分区是 ClickHouse 管理数据的逻辑分组,通过建表语句中的

PARTITION BY

语句定义。

示例:

CREATE TABLE events (

event_date Date,

user_id UInt32,

action String

)

ENGINE = MergeTree()

PARTITION BY toYYYYMM(event_date) -- <== 定义分区规则

ORDER BY (user_id, event_date);

这表示表中的数据将根据 event_date 的年月来分区,即:

202407 的数据会放在一个分区,

202408 的数据放在另一个分区。

🧱 2️⃣ 特点与作用

特性 说明

逻辑分组 用来对数据进行按时间或业务字段的划分

存储隔离 每个分区的数据在磁盘上是独立目录

管理粒度 可以删除或移动整个分区

查询加速 查询时智能裁剪不相关的分区,加快速度

📦 3️⃣ 分区示例(存储路径)

在磁盘上类似:

/var/lib/clickhouse/data/db_name/table_name/

├── 202407/

│ ├── 20240701_20240701_1_1_0/

│ ├── 20240702_20240702_2_2_0/

│ └── ...

├── 202408/

│ ├── 20240801_20240801_1_1_0/

│ └── ...

202407、202408 是分区名,目录下每个子目录就是一个 part。

三、Part(数据分片)

🧩 1️⃣ 定义

part 是分区下的物理数据块,每次插入(INSERT)都会生成一个新的 part(一个目录)。

例如:

20240701_20240701_1_1_0/

20240701_20240701_2_2_0/

每个 part 里包含了数据文件,比如:

primary.idx

columns.txt

checksums.txt

count.txt

data.bin

⚙️ 2️⃣ Part 的意义:

项目 说明

存储单元 表的最小物理数据单元

生成机制 每次批量插入都会生成一个新 part

合并机制 后台会自动把多个小 part 合并成一个大 part(Merge)

删除机制 删除分区或 TTL 到期会删除对应 part

查询机制 查询时会扫描多个活跃的 part 数据文件

四、分区 vs Part 的关系

对比项 分区(Partition) Part(数据分片)

层级 上层逻辑分组 分区内的物理文件块

定义时机 建表时由 PARTITION BY 决定 每次 INSERT 或 MERGE 生成

数量 分区通常按天/月/字段生成 一个分区下可能有成百上千个 part

作用 控制数据逻辑范围(生命周期、清理策略) 控制存储与读写性能

存储位置 /data/db/table/分区名/ /data/db/table/分区名/part目录/

管理命令 ALTER TABLE DROP PARTITION, DETACH PARTITION ALTER TABLE DROP PART

典型问题 太多分区会影响管理 太多小 part 会影响性能

五、举例说明

建表并按月分区:

CREATE TABLE user_logs

(

dt Date,

uid UInt64,

msg String

)

ENGINE = MergeTree()

PARTITION BY toYYYYMM(dt)

ORDER BY (uid, dt);

你每天往表中插入一次数据,那:

每个月会有一个分区,例如 202407;

每天插入一次,就会在分区 202407 下产生一个 part;

如果每天批量插入次数多,比如每分钟插入一次,就会产生成千上万个 part。

六、如何查看分区和 part 信息

查看分区

SELECT

table,

partition,

count() AS parts,

sum(rows) AS total_rows

FROM system.parts

WHERE table = 'user_logs' AND active = 1

GROUP BY table, partition;

查看所有 part 详情

SELECT

table,

partition,

name AS part_name,

active,

rows,

bytes_on_disk

FROM system.parts

WHERE table = 'user_logs';

七、总结对比

项目 分区 (Partition) 数据分片 (Part)

含义 表的逻辑划分 表的物理存储单元

来源 PARTITION BY 决定 INSERT 或合并产生

生命周期 可整体删除、移动 被合并、删除后消失

数量 一般较少(月/天) 可能很多(成百上千)

优化重点 合理分区粒度 控制小 part 数量

查看系统表 system.parts system.parts

换句话说:

分区(Partition) = 逻辑上的"一组数据"

Part(数据分片) = 存储这一组数据的若干文件块。

一个分区下面有很多个 part,ClickHouse 后台会不断合并这些 part 来保持性能。

相关推荐
笃行35014 小时前
金仓数据库数据安全双防线:静态存储加密与传输加密实战
数据库
笃行35014 小时前
金仓数据库物理备份实战:sys_rman 全流程演练与误覆盖抢救
数据库
笃行35014 小时前
金仓数据库逻辑备份实战:从全库导出到 Schema 替换的完整闭环
数据库
戴为沐20 小时前
Linux内存扩容指南
linux
zylyehuo1 天前
Linux 彻底且安全地删除文件
linux
SelectDB1 天前
阶跃星辰基于 SelectDB 构建 PB 级 Agent 可观测平台
大数据·数据库·aigc
这个DBA有点耶2 天前
GROUP BY优化全解:如何写出既不丢数据又飞快的分组查询
数据库·mysql·架构
掉头发的王富贵2 天前
【StarRocks】极限十分钟入门StarRocks
数据库·sql·mysql
Nturmoils2 天前
WHERE 条件别凭习惯写,常用查询先跑一遍
数据库