ClickHouse 类型怎么选
ClickHouse 的类型分整数、浮点、定点、字符串、日期时间与半结构化几类。选型原则是能用整型就不上浮点、低基数字符串加 LowCardinality 编码、非必要不用 Nullable;类型一旦写进表结构,后续修改往往要重组数据,代价不小。
基本信息
| 整数 | UInt8/16/32/64、Int8…Int64,按取值范围选最小够用的 |
|---|---|
| 浮点与定点 | Float32/64 用于近似计算,Decimal(P,S) 保存精确小数 |
| 字符串 | String、FixedString(N)、LowCardinality(String) 字典编码 |
| 时间 | Date、Date32、DateTime、DateTime64(3) 毫秒、DateTime64(9) 纳秒 |
| 复合与特殊 | Array(T)、Tuple、Map(K,V)、Nullable(T)、Enum8/16、UUID |
典型使用场景
- 计数与 ID 用整型,取值范围决定占多少位
- 金额、比率用 Decimal,避免浮点误差在多轮累加后放大
- 地区、状态这类低基数字段用 LowCardinality 节省内存与 IO
- 毫秒、微秒级时间戳用 DateTime64 指定精度
- 结构不确定的日志字段先用 String 存原始内容,后续再按需拆列
建表与类型转换
建表与类型转换
CREATE TABLE demo
(
id UInt64,
created DateTime64(3), -- 毫秒精度时间
region LowCardinality(String), -- 低基数,字典编码
score Decimal(10, 2), -- 精确小数
tags Array(String),
note Nullable(String) -- 非必要不用
)
ENGINE = MergeTree
ORDER BY id;
-- 查看列的实际类型
DESCRIBE TABLE demo;
-- 转换时显式兜底,避免个别脏值导致整批写入失败
SELECT toUInt64OrZero('abc') AS bad_cast, toDateOrNull('2026-13-01') AS bad_date;类型选择对照
| 类型 | 适用场景 | 注意 |
|---|---|---|
| UInt / Int 家族 | 计数、ID、枚举值 | 取值可能为负时不能用 UInt |
| Float32 / Float64 | 确实允许近似计算的场景 | 等值比较不可靠,金额不要用 |
| Decimal(P,S) | 金额、比率等精确小数 | 算术有额外开销,纯整数统计不必用 |
| LowCardinality(String) | 取值种类少的字符串 | 基数字段很高时反而增加开销 |
| DateTime64(3) | 毫秒级时间戳 | 精度越高存储越大,按需求选 |
| Nullable(T) | 确实允许缺失的列 | 附加存在性文件,聚合与关联要额外判断 |
Nullable 会为列附加独立的存在性文件,读写与聚合都要多一层判断;能用普通类型加默认值表达缺失语义时,优先选择普通类型。
导入外部数据时不要依赖隐式转换:脏值会让整批插入失败,用 toUInt64OrZero、toDateOrNull 这类带兜底的转换函数显式处理,把异常值规整成可统计的默认值。