无边界堆列是什么
「大宽事实表」反模式指把下单、支付、退款、售后等不同业务过程的字段全塞进一张事实表,列数上百、每行大量空值。后果是三重的:表稀疏导致存储与扫描成本高,字段归属混乱导致维护困难,不同过程粒度不一致导致聚合重复计数。正确做法是按业务过程拆表,每张事实表只放本过程的度量与维度键,密度优先、口径单一。
基本信息
| 典型症状 | 列数持续膨胀、行内空值过半 |
|---|---|
| 根因 | 把主题当过程,追求一张表查全部 |
| 治理方向 | 按业务过程拆表 + 共享一致性维度 |
| 硬判断线 | 一张表出现两种粒度就必须拆 |
典型使用场景
- 业务方要求「一张表查所有交易指标」时,用拆表加汇总层满足,而不是无止境堆列
- 新场景接入:先判断它属于哪个业务过程,同过程加列,不同过程开新表
- 老宽表治理:把低频场景字段迁到独立事实表,原表只留核心过程
- 性能治理:宽表扫描列多、压缩率低,拆表后单表扫描量显著下降
- 口径治理:同一列在不同场景有两种含义时,拆分后各自命名并登记口径
拆分信号自查
拆分信号自查
-- 1) 列数:宽表通常几百列,正常事实表多为几十列以内
SELECT count(1) AS col_cnt FROM information_schema.columns WHERE table_name='fact_all';
-- 2) 稀疏度:统计关键列的空值率,超过一半说明字段覆盖过程不一致
SELECT
sum(CASE WHEN pay_amt IS NULL THEN 1 ELSE 0 END) / count(1) AS pay_null_rate,
sum(CASE WHEN refund_amt IS NULL THEN 1 ELSE 0 END) / count(1) AS refund_null_rate
FROM fact_all; -- 空值率高的场景应拆到独立事实表拆分信号与处理
| 信号 | 判断依据 | 处理方式 |
|---|---|---|
| 列数持续增长 | 每季度都有新场景加列 | 按业务过程拆表 |
| 行内空值占比过半 | 字段覆盖的过程不一致 | 低频场景字段移出 |
| 同一表两种粒度 | 订单行与支付行混存 | 拆表并各自声明粒度 |
| 同列多种语义 | 不同场景含义不同 | 拆列改名并分别登记口径 |
拆分依据是业务过程与粒度,不是主题名词。「交易」是主题,「下单」「支付」「退款」是业务过程,一张事实表对应一个过程。