首页/数据/数仓建模速查/事实表状态列与状态时间戳
维度与事实设计149 条

事实表状态列与状态时间戳

订单/工单状态若需历史轨迹:用状态时间戳行(每状态一行)或累积快照;单列状态原地覆盖会丢失历史,无法做状态演进分析。

数仓建模速查数据更新于 2026-10-13

状态要留历史

订单、工单这类有生命周期的事实,状态若只存最新值,原地覆盖会丢掉过程,状态演进与停留时长分析就无从做起。常见方案有两种:状态事件表每次状态变更写一行,保留时间戳与操作者,适合分析各状态停留多久、卡在哪个环节;累积快照在每个里程碑放时间列,适合快速看当前进度与分段耗时。选哪一种取决于要回答的问题,两者也可以并存。

基本信息

方案一状态事件表,每次变更一行
方案二累积快照,多个里程碑时间列
禁忌做法单列状态原地覆盖
事件表字段状态、状态时间、操作者、批次
选型依据看停留时长用事件行,看当前进度用快照

典型使用场景

  • 分析订单从下单到发货各环节的停留时长,定位瓶颈环节
  • 监控超期未流转的工单,作为待办提醒与考核依据
  • 状态回退的审计:已支付改为已取消这类变更需要留痕
  • 客服查看订单当前进度,直接读累积快照即可
  • 质量检查:状态时间倒挂(先签收后发货)需要被拦截

状态事件与停留时长

状态事件与停留时长
-- 状态事件表:每次变更一行,保留操作者
CREATE TABLE fact_order_status_event (
  order_id  string,
  status    string    COMMENT '状态值',
  status_ts timestamp COMMENT '状态发生时间',
  operator  string    COMMENT '操作方或系统名',
  batch_id  string    COMMENT '写入批次'
) PARTITIONED BY (dt string) STORED AS ORC;

-- 停留时长:相邻状态的间隔
SELECT order_id, status,
       timestampdiff(hour, status_ts,
         lead(status_ts) OVER (PARTITION BY order_id ORDER BY status_ts)) AS stay_h
FROM fact_order_status_event;

方案对照

方案数据形态适用问题
状态事件表一变更一行停留时长、流转路径、责任方
累积快照一实例一行多时间列当前进度、分段耗时对比
状态宽表仅保留最新状态实时看板,无历史可查
状态字典状态值与中文名映射统一各系统的状态命名
状态值要先做字典归一:不同系统对「已发货」的编码可能不同,不统一就会出现同一环节被统计成两个状态、下钻时数字相互矛盾。
状态回退要允许出现并如实记录:驳回、取消、重新发货都是真实业务,用约束硬挡会让数据失真,正确做法是记录并在指标层定义口径。

易错点

  • 状态只存最新值,原地覆盖导致演进分析无法开展
  • 事件表没有操作者与批次,异常流转无法追责
  • 状态值未归一,同一环节在不同系统被统计成两个状态
  • 状态时间倒挂不做校验,时效指标出现负值

数据来源与参考

  • 数据仓库工具箱:状态历史设计
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌