CREATE TABLE 是什么
CREATE TABLE 是 ClickHouse 的建表入口:三要素是列定义、表引擎与排序键。MergeTree 家族必须写 ORDER BY,可选 PARTITION BY、PRIMARY KEY、SAMPLE BY、TTL 与 SETTINGS。列定义支持默认值表达式、压缩编解码与注释,列的顺序决定 SELECT * 的输出顺序,导入外部数据时顺序错位会静默写错字段。
基本信息
| 最小结构 | CREATE TABLE t (…) ENGINE = MergeTree ORDER BY (…) |
|---|---|
| 可选子句 | PARTITION BY、PRIMARY KEY、SAMPLE BY、TTL、SETTINGS、COMMENT |
| 列定义 | 名称 类型 [DEFAULT|MATERIALIZED|ALIAS 表达式] [CODEC(...)] [COMMENT ...] |
| 建表变体 | CREATE TABLE t AS other_table 复制结构;AS SELECT 建表并灌数据 |
| 分布式 | ON CLUSTER 让语句在所有节点执行 |
| 适用版本 | ClickHouse 22.x 及以上语法稳定 |
典型使用场景
- 新建明细表并按查询模式设计排序键
- 按月或按日分区,便于整块清理历史数据
- 复制现有表结构创建同构新表
- 用 AS SELECT 从查询结果快速建表
- 在集群上统一建表,避免逐节点手工执行
- 给高频读取的列设置压缩编码节省存储
示例
示例
CREATE TABLE IF NOT EXISTS analytics.events
(
event_time DateTime,
event_date Date DEFAULT toDate(event_time), -- 派生列,写入时可省略
user_id UInt64,
event_type LowCardinality(String), -- 低基数字典编码
props String CODEC(ZSTD(3)) -- 单独指定压缩算法
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(event_time) -- 按月分区
ORDER BY (event_type, user_id, event_time) -- 排序键
SETTINGS index_granularity = 8192; -- 稀疏索引粒度列定义修饰符
| 修饰符 | 作用 | 注意点 |
|---|---|---|
| DEFAULT | 缺省值表达式 | 写入时未给值则计算 |
| MATERIALIZED | 始终按表达式计算 | 不能显式写入,也不出现在 INSERT 列里 |
| ALIAS | 查询期计算的别名列 | 不落盘,不能直接写入 |
| CODEC | 列级压缩编码 | 如 ZSTD、Delta、DoubleDelta |
| COMMENT | 列注释 | 便于他人理解业务含义 |
也可以用 CREATE TABLE t AS other_table 复制结构(引擎同名复制),或 AS SELECT 建表并灌数据。
集群环境用 ON CLUSTER 建表,能保证各节点的表结构与复制表路径一致,减少手工操作带来的偏差。
排序键决定数据在分区内的物理顺序,也是稀疏索引的取样依据;不写 PRIMARY KEY 时它默认等于 ORDER BY。排序键应以查询里最常用的过滤列开头,同时让相邻数据尽量相似以利压缩,两件事需要一起权衡。
如果只是想让结构一致的副本表跟随集群建表,可以用 Replicated 数据库或 ON CLUSTER 配合副本表引擎,省掉逐个节点手工建表;建完先用 SHOW CREATE TABLE 核对实际生效的语句,再灌数据。
MergeTree 家族即使写成 ENGINE = MergeTree() 也必须给 ORDER BY,否则建表直接报错。