4. 事实表设计:三种快照模型的应用场景
事实表设计,说白了就是回答一个问题:你要度量什么? 度量粒度怎么切,直接决定了查询能不能跑得动。我见过太多团队一上来就建一张超级大宽表,结果跑个月度汇总要半小时——这就是事实表类型选错了。
事实表有三种经典类型:事务事实表、周期快照事实表、累积快照事实表。它们不是互斥的,实际项目中经常混着用。嗯,我们先搞清楚各自长什么样。
4.1 事务事实表:记录每一次发生
事务事实表,就是每发生一笔业务,就记一行。比如电商订单,用户下一单,订单表里就多一条记录。这是最基础、最常用的事实表类型。
我在项目中遇到过这样一个场景:某电商平台要分析用户下单行为,每天几百万笔订单。如果用事务事实表,直接按订单ID做主键,每笔订单一行。查询「昨天每个品类的销售额」时,直接 sum 金额字段,按品类分组就行——快得很。
适用场景:
- 需要分析单个事件细节(如每笔订单的金额、时间)
- 需要做事件计数(如每天下单次数)
- 维度变化不频繁,或者变化时用退化维度处理
避坑指南: 我曾经犯过一个错——把事务事实表当成万能表。有个金融项目,客户要查「每个账户截至昨天的累计余额」,我直接用事务事实表去 sum 所有交易流水。结果呢?每天跑一次全量扫描,几十亿行数据,跑一次要两小时。后来改成周期快照,问题才解决。
4.2 周期快照事实表:定期拍一张照片
周期快照,就是每隔固定时间(比如每天、每小时)把业务状态「拍一张照」。每一行代表某个对象在某个时间点的快照。数据量比事务事实表小得多,因为它是按周期聚合的。
你想想看,银行每天都要算每个账户的日终余额。如果用事务事实表,得把当天所有交易流水累加一遍。但用周期快照,每天只存一行:账户ID、日期、日终余额。查询「上个月每个账户的平均余额」时,直接 sum 日终余额再除以天数,几秒钟就出结果。
适用场景:
- 需要分析某个时间点的状态(如库存量、账户余额)
- 需要做周期性汇总(如月度销售目标完成率)
- 事务数据量太大,但业务只需要周期汇总结果
| 对比维度 | 事务事实表 | 周期快照事实表 |
|---|---|---|
| 粒度 | 每笔事件一行 | 每个周期每个对象一行 |
| 数据量 | 大(随事件数增长) | 小(随周期数增长) |
| 典型查询 | 某段时间内的事件统计 | 某个时间点的状态或周期内累计 |
| 更新方式 | 只追加,不更新 | 覆盖或追加(取决于设计) |
我个人习惯,在数据量超过 10 亿行的事务表上,如果业务只需要日报、月报,优先考虑周期快照。能省掉 90% 的存储和查询时间。
4.3 累积快照事实表:跟踪一个流程的完整生命周期
累积快照,专门用来跟踪一个业务流程从开始到结束的完整状态。每一行代表一个业务实例(比如一个订单、一个工单),但这一行会随着流程推进不断更新。
举个例子:电商订单从「下单」到「支付」到「发货」到「签收」,每个阶段都有时间戳。用累积快照,一行就搞定:订单ID、下单时间、支付时间、发货时间、签收时间、当前状态。查询「平均从下单到签收要多久」时,直接算签收时间减下单时间,一行一个订单,快得飞起。
适用场景:
- 需要分析流程耗时(如订单履约时长、工单处理时长)
- 需要跟踪流程当前状态(如哪些订单还在「待支付」)
- 流程阶段固定,且每个阶段都有明确的时间点
避坑指南: 我曾经在一个物流项目里,用累积快照跟踪包裹流转。一开始只设计了 5 个阶段,后来业务加了 3 个新环节,结果表结构要改,历史数据要重刷——折腾了两周。所以,累积快照适合流程相对稳定的场景。如果流程经常变,建议用事务事实表加状态字段,或者用周期快照。
4.4 三种事实表的选择策略
实际项目中,这三种表不是选一个就行。我通常的做法是:事务事实表做明细查询,周期快照做汇总报表,累积快照做流程分析。三张表并存,各司其职。
举个例子,电商数据仓库:
- 事务事实表: 订单明细表,每笔订单一行,用于分析用户行为、商品销售趋势
- 周期快照: 每日订单汇总表,每天每个店铺一行,用于生成日报、月报
- 累积快照: 订单履约进度表,每个订单一行,用于分析履约效率、异常订单
你想想看,如果只用事务事实表,查「昨天每个店铺的销售额」要扫描几百万行;用周期快照,直接读几千行。如果只用周期快照,查「某个订单现在到哪一步了」又得去翻明细。所以,按查询场景建不同的表,才是真正的性能优化。
4.5 一张图看懂三种事实表
下面这张图,帮你快速理清三种事实表的区别和选择逻辑。
4.6 实战建议
最后,分享几个我踩过的坑和总结的经验:
- 不要一开始就建周期快照。 先跑事务事实表,等数据量上来了,发现查询慢了,再考虑加周期快照。过早优化是万恶之源。
- 累积快照的更新频率要控制好。 我见过有人每 5 分钟更新一次累积快照,结果表锁频繁,查询反而更慢。一般按业务节奏来,比如每天更新一次就够了。
- 三种表可以共享维度。 维度表设计好了,事实表随便换。这也是星型模型的好处——维度复用,事实表灵活。
- 别忘了清理历史数据。 事务事实表的数据量增长很快,超过一定时间范围的历史数据,可以归档到冷存储,或者直接删掉。我一般保留 90 天明细,更早的用周期快照替代。