累积快照的更新方式
累积快照里一行代表一个业务实例(一张订单、一笔贷款申请)的完整生命周期,随着流程推进不断更新同一行的里程碑列。它和事务事实表正好相反:行数不随事件数量增长,而是同一行被反复改写。两个硬约束:里程碑时间只允许从空到有、不允许回退;更新必须幂等,同一批数据重跑不能把已完成的节点写回空值。
基本信息
| 粒度 | 一个业务实例一行 |
|---|---|
| 更新实现 | MERGE 更新,或整分区重写 |
| 里程碑列 | 下单、支付、发货、签收等时间戳 |
| 核心约束 | 时间戳单调,只从空到有 |
| 幂等要求 | 同批重跑,已完成节点不被覆盖 |
典型使用场景
- 订单履约时效:从下单到签收各段耗时,一行即可算完
- 信贷审批流程:各审核节点时间戳与停留时长
- 工单处理链路:受理、派单、处理、关闭的流转分析
- 物流节点跟踪:揽收、中转、派送、签收的时间序列
- 转化漏斗:同一实例是否走到下一步,判断流失环节
MERGE 更新
MERGE 更新
-- 用 coalesce 保证已完成节点不被后到的空值覆盖
MERGE INTO fact_order_flow t
USING stg_order_flow s ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET
t.pay_ts = coalesce(t.pay_ts, s.pay_ts),
t.ship_ts = coalesce(t.ship_ts, s.ship_ts),
t.sign_ts = coalesce(t.sign_ts, s.sign_ts),
t.last_update_ts = s.update_ts
WHEN NOT MATCHED THEN INSERT VALUES
(s.order_id, s.create_ts, s.pay_ts, s.ship_ts, s.sign_ts, s.update_ts);关键列与异常
| 列 | 含义 | 异常表现 |
|---|---|---|
| create_ts | 实例创建时间,应为非空 | 为空说明源端字段缺失或首个节点未回传 |
| pay_ts 等节点列 | 首次到达该节点的时间 | 补数被小值覆盖,耗时算成负数 |
| last_update_ts | 最近一次被更新的时间 | 不增长说明上游批次没跑到这张表 |
| 派生耗时列 | 相邻节点时间差 | 节点空值时不能直接相减,需置空 |
节点时间取首次到达的时间,不要取最后一次:取消后重新支付、发货后改单都会让时间戳后移,取末次会把真实的流程时效拉长。取消与关闭单加独立标记,不参与时效样本,否则平均值偏乐观。
并发写入同一行会互相覆盖里程碑:流任务与批任务同时更新同一批订单时,必须约定只有一个写入方,或用乐观锁(按 last_update_ts 版本号)控制,否则会出现节点丢失。