物理模型设计要点
物理设计关注五件事:字段类型与精度、分区方式、排序或聚簇键、受控冗余列、压缩与编码。原则是用查询模式驱动设计,而不是照搬源系统的类型与约束。分区键通常选时间或高频过滤的业务字段,排序键优先放常用过滤与 join 列。设计完成后要压测验证,因为物理设计决定了扫描量与关联代价,而它相对逻辑模型更容易调整,属于性价比很高的优化手段。
基本信息
| 类型精度 | 按取值范围选择,避免一律用超长字符串 |
|---|---|
| 分区键 | 时间或高频过滤字段,注意分区数量增长 |
| 排序或聚簇键 | 常用过滤与 join 列优先,高基数等值列优于低基数枚举 |
| 冗余列 | 受控冗余原维表属性,减少 join 次数 |
| 验证方式 | 按真实查询压测,观察扫描量与响应时间 |
典型使用场景
- 大事实表分区设计:按日分区配合时间过滤,实现分区裁剪
- 报表加速:把高频过滤列放进排序键,降低扫描数据量
- 成本优化:合理压缩与编码可显著降低存储与 IO 开销
- 宽表加工:受控冗余常用维度属性,减少大表 join
- 引擎迁移:不同引擎对分区与排序的支持不同,需要按目标引擎重设
物理设计示例
物理设计示例
-- 排序键按查询模式排列:高频等值过滤列在前
-- 常用查询:按日期范围过滤 + 按商品关联
PARTITIONED BY (dt string) -- 按日分区,支撑时间裁剪
CLUSTERED BY (product_sk) SORTED BY (dt) INTO 64 BUCKETS -- 分桶降低 join 代价
STORED AS ORC -- 列存 + 压缩,降低扫描与存储
TBLPROPERTIES ('orc.compress' = 'ZLIB');
-- 冗余示例:把高频使用的类目名称直接存在事实表,减少一次 join
-- category_l1 string COMMENT '冗余自 dim_product,加快固定报表'设计决策对照
| 要素 | 推荐做法 | 常见错误 |
|---|---|---|
| 字段类型 | 按取值范围选,金额用定点或整数分 | 全部用超长字符串,存储浪费 |
| 分区键 | 时间或高基数业务字段 | 低基数枚举,分区数失控 |
| 排序键 | 高频过滤与 join 列在前 | 与查询模式脱节,扫描量不降 |
| 冗余列 | 只冗余稳定且高频的属性 | 冗余易变属性,回刷成本高 |
物理设计的变更成本低于逻辑模型:改排序键或分区只需重建数据,不动口径。因此性能问题优先在物理层解决,而不是回头改粒度。
不同引擎对排序键、聚簇键的支持差异较大,设计方案要写清目标引擎与版本;同一套 DDL 在不同引擎上未必有相同的执行效果。