交易事实:每个状态事件一行
累积快照:每个订单一行
里程碑:创建、支付、发货、签收
时长:阶段间隔与当前积压
更新:迟到、重开与回退
结论:分析流程时累积快照更直接,审计事件时交易事实更完整
事件事实适合回答每天发生多少支付或发货,累积快照适合回答当前有多少订单卡在发货前、平均履约多久。
重要业务通常同时保留原始事件和面向流程分析的快照。
先定义一行的生命周期实体
一行可能是一笔订单、一个订单行、一次工单或一个申请。若订单可拆分多次发货,订单行或履约单可能是更合适粒度。
粒度错误会让里程碑日期和时长无法唯一确定。
里程碑与时长可更新
创建时先写已知日期,其余为空;支付、发货和签收发生后更新同一行,并计算计划与实际时长。
保留首次和最终日期,明确重开、回退和多次事件如何处理。
快照更新需要幂等和历史证据
乱序事件、重复消息和状态更正不能让里程碑倒退或重复计算。使用事件标识、版本和更新时间控制。
若需要知道“昨天当时看到的状态”,还需周期快照或变更历史,累积快照本身只表示最新流程状态。
用异常流程验收
测试正常流程、跳过步骤、部分发货、取消、重开、迟到事件和重复事件,核对积压、阶段时长和最终完成率。
BuildTable 可作为事实模型设计候选;增量更新、事件去重和历史快照编排需逐项确认。
先用业务过程确定快照粒度
累积快照的一行必须对应一个可以走完相对稳定里程碑的流程实例。若订单可拆成多个包裹,订单粒度只有一个 ship_date 会丢失部分发货;这时履约单或订单行可能更合适。保险理赔、招聘申请和维修工单同理。先画状态与事件,再选择能唯一表达每个里程碑的最细稳定实体。
粒度声明应写在表名、模型文档和唯一测试中,例如“一行代表一个 fulfillment_id 的当前生命周期”。事实外键连接客户、商品、地点和渠道,里程碑日期使用角色维度,阶段时长和当前状态是可更新事实。不要在同表混入订单行和整单费用造成重复。
事件事实、累积快照和周期快照各司其职
交易事件表一行一个创建、支付、发货、签收或取消事件,适合审计和按发生日计数;累积快照一行一个流程,适合当前积压、阶段时长和漏斗;周期快照保存每天或每周当时状态,适合回答“月底有多少在途”。三者不是互斥替代,而是针对不同时间问题的投影。
推荐保留不可变事件作为源证据,再派生累积快照。需要历史在途趋势时,定期从快照生成周期事实,或保留有效期变更记录。仅有累积快照无法还原昨天看到的状态;仅有事件表则每次计算当前阶段都需复杂排序与状态逻辑。
里程碑更新必须幂等并处理乱序
每个事件需要 event_id、source_version、event_time 和 ingested_at。重复事件不得重复改变快照,晚到的早期事件可补充空里程碑,但不能覆盖已确认的更高版本;源系统更正则通过明确的撤销或版本规则处理。更新条件应比较业务时间和版本,而不是简单“最后到达覆盖”。
对于多次发生的事件,区分 first_paid_at、last_paid_at 或计数;取消后重开要决定是否仍是同一流程实例。阶段时长只在两个有效里程碑存在且顺序合理时计算,负时长进入质量队列。快照更新失败需要可重放,且重放结果与首次处理一致。
计划日期让快照支持过程绩效
累积快照不仅保存实际日期,还可保存 promised_ship_date、target_delivery_date 等计划里程碑。由此可计算计划与实际差异、当前逾期和预计风险。计划若会变,应明确保存初始承诺、当前承诺或变更历史;只覆盖一个字段会失去承诺漂移证据。
当前积压定义也需业务契约:已支付未发货、创建未取消还是所有未签收?不同团队会得到不同漏斗。为每个阶段定义进入条件、退出条件、超时阈值和排除状态,使 KPI 与快照状态机一致,而不是由查询临时拼接。
异常流程验收与 BuildTable 边界
测试正常、跳步、部分履约、多次支付、取消、重开、事件重复、乱序、迟到、更正和源系统重放。核对事件数、流程唯一数、当前状态、每段时长与周期快照守恒;故意中断加载后重跑,验证代理键和里程碑不变。
BuildTable 可作为事实模型设计候选,但增量合并、事件去重、状态机、周期快照和回填编排能力需实际核验。若流程高度分支、可无限循环或没有稳定终点,单一累积快照可能不适合,应优先保留事件模型并构建面向具体问题的投影。
一份可执行的增量合并契约
契约定义流程主键、事件唯一键、里程碑优先级、first/last 规则、允许回退、取消与重开语义、计划日期版本、迟到容忍和重放窗口。合并前保存源事件和版本,更新时只改受影响行,并记录 old_state、new_state 与触发事件。失败批次可重复运行且结果一致,禁止按到达顺序简单覆盖。
每日质量检查流程数、各状态数量、空里程碑、负时长、异常跳转、重复事件和事件到快照的覆盖率,并与周期快照对账。指标负责人确认积压阶段和超时阈值,数据负责人维护状态机。若流程规则频繁变更,应把规则版本写入快照,使历史 KPI 能按当时或当前规则分别解释。
发布前从源事件重建一个完整月份,与生产快照逐行比较;再随机打乱事件到达顺序并重复加载,结果仍应一致。对部分发货和重开流程,由业务负责人逐例确认粒度与最终状态。若无法写出唯一结果,说明流程实体或状态规则尚未定义好,不应先优化 SQL。
