事务事实表

事务事实表记录每次业务事件,只追加不修改,是粒度最细、用途最广的事实表;可加度量(金额、数量)在这里定义,留存、复购等分析都由它派生。

事务事实表是什么

事务事实表记录每一次业务事件,只追加不修改,是粒度最细、用途最广的事实表。可加度量(金额、数量、折扣)在这里定义,留存、复购、漏斗等分析都由它聚合或派生。因为只追加,它同时也是最好的「事实底账」:任何汇总口径出现争议,都可以回到明细层重新算一遍。

基本信息

粒度一次事件一行
写入方式按分区追加,重跑时用分区覆盖
度量类型金额、数量、折扣等可加字段
派生关系汇总表与快照都由它聚合而来

典型使用场景

  • 交易明细:下单、支付、退款事件逐条落表
  • 用户行为分析:登录、下单、领券等事件用于留存与漏斗
  • 事实底账:口径争议时回到明细重新计算
  • 下游汇总:日、月汇总表与指标都由事务表聚合
  • 审计追溯:需要定位到单笔记录的核账场景

建表与写入

建表与写入
CREATE TABLE fact_trade_order (
  order_id BIGINT, date_sk INT, user_sk BIGINT, product_sk BIGINT,
  pay_amount DECIMAL(18,2), qty INT
) PARTITIONED BY (dt STRING);     -- 按业务日期分区,便于重跑覆盖

INSERT OVERWRITE TABLE fact_trade_order PARTITION (dt='2026-10-11')
SELECT order_id, date_sk, user_sk, product_sk, pay_amount, qty
FROM dwd_trade_order_detail_di WHERE dt='2026-10-11';   -- 覆盖写,保证幂等可重跑

字段设计要点

字段含义注意点
业务主键订单号、支付流水号用于去重与回溯,必须唯一
维度代理键date_sk、user_sk 等关联维度表,支持按当时属性分析
可加度量pay_amount、qty可以直接 sum 汇总
不可加度量单价、转化率只能存分子分母,不能直接求和
分区字段dt 业务日期重跑覆盖的边界依据
事务事实表要保证事件只落一次:上游重跑时用分区覆盖写入而不是追加,否则同一事件会出现多行,所有汇总都会偏大。
把不可加度量(比率、单价)直接存进事实表并参与求和会让汇总严重失真,正确做法是保留分子与分母,在汇总层再算比率。

重跑退化的边界

事务事实表以「按业务日期分区覆盖」保证幂等,但有两个边界要留意:一是迟到数据,事件发生在昨天、今天才到达,只覆盖今天的写入会把历史补订留在原分区之外,需要用重叠窗口或额外的补偿流程;二是撤单与退款,它们本身也是新事件,应该以新行记录而不是修改原行,否则事实表就不再是只追加的底账,历史重算的口径会随当前状态漂移。

易错点

  • 用 INSERT INTO 追加写入重跑的分区,产生重复事件行
  • 把不可加比率直接存进事实表,汇总时数值失真
  • 分区字段用数据写入时间而不是业务时间,补数时无法按业务日期覆盖
  • 事实表里塞进大量描述属性,事实与维度的边界被打破,表越来越宽

数据来源与参考

  • Kimball《The Data Warehouse Toolkit》事务事实表
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌