双时态模型
01

Valid:业务世界生效区间

02

System:仓库记录区间

03

As-was:当时已知视图

04

Restated:按最新知识回看

05

Evidence:变更原因与版本

结论:一个生效日期不足以解释历史

合同 8 月 1 日生效,9 月 1 日才录入。若只存 updated_at,无法回答 8 月实际适用什么;若直接覆盖 effective_date,8 月已发布报表会悄悄改变。双时态分别记录 valid time 与 system time。

valid_from/valid_to 表示业务事实适用区间,system_from/system_to 表示该版本何时进入仓库。这样既能按最新知识重述 8 月,也能复现 8 月 15 日系统当时知道的内容。

先判断哪些事实需要两条时间轴

合同、价格、组织归属、保单、主数据映射和会计修正常有迟到或追溯变更,适合双时态。不可变交易事件通常保留 event_time 与 ingestion_time 已足够,不必所有表都增加复杂度。

建模前列出业务问题:要看事实发生时、录入时、发布时还是当前重述?如果没有“当时知道什么”的审计需求,简单有效期维度可能更经济。

声明半开区间和时间精度

建议区间采用 [from,to),避免相邻版本在边界重复命中。统一时区、精度和无穷结束表示;日期级政策不能伪装成秒级。

同一业务键在 valid 轴允许追溯切分,但任一 system 快照下有效区间不应重叠,除非业务明确允许多状态。约束与质量测试必须表达这一规则。

修正应关闭系统版本而非覆盖

收到迟到合同后,关闭当前 system_to,插入反映新知识的版本;若追溯生效区间切分,还需保留未受影响片段。每次变更带 reason、source、actor、run_id 和审批。

直接 UPDATE 丢失系统历史。仅依赖数据库 temporal 功能也不自动提供业务有效时间;应用或 ETL 仍需正确切分 valid 区间。

事实关联必须声明使用哪种视图

交易事实按 event_time 关联当时有效维度,可生成 latest-restated 视图;若复现历史发布,则还要限定 system time 为当时关账或发布时刻。

只写 BETWEEN valid_from AND valid_to 不足以双时态查询。语义层提供 as_was、as_is 和 restated 等明确名称,避免报表作者随意选择。

处理迟到、删除与撤销

迟到变更可能影响已关闭期间,是否重述由业务政策决定。模型记录 detected_at、approved_at 和 restatement_id,使数据管道执行已批准动作,不替代财务或法律判断。

删除可能是业务失效、录入错误或隐私删除,含义不同。业务撤销产生新有效版本;纠错保留受控审计;隐私删除按法规传播并可能降低完整复现能力。

建立发布快照和重述差异

每次正式发布保存 release_id、system_cutoff、data_watermark 与政策版本。用户查看旧报告时默认读取原发布,若切换最新重述则展示差异和原因。

差异按新增迟到事实、有效期修正、映射变化和计算规则分类。不要把所有差异归为“数据更新”,这无法支持复核。

性能设计不能破坏语义

四个时间列和版本会增加行数与范围 Join 成本。可按业务键和时间索引、分区、生成当前视图、预物化常用快照,但原始版本仍保留。

优化后测试边界、重叠和快照等价。为了速度只保留 current=true 会让系统退化成不可复现的覆盖模型。

反例与验收

测试追溯生效、未来生效、同日两次修正、相邻边界、跨时区、撤销、迟到事实和隐私删除。检查任一系统时刻下有效区间唯一,原发布可重放,重述差异可解释。

用已知合同样本手工画两条时间轴,与查询结果逐点核对。总量在切分前后守恒,除非变更本身明确改变业务金额。

ETL 实现要覆盖区间切分的全部情形

输入变更先按业务键排序,锁定当前 system 版本,再计算 valid 区间的交集与差集。追溯变更可能产生“变更前片段、新片段、变更后片段”三行;每行继承来源证据,并以一个 change_set_id 关联。

作业重试以 source_event_id 幂等,不能重复切分。并发修正使用乐观版本或串行队列,冲突进入人工队列;若源系统撤回事件,生成补偿版本而非删除已发布系统历史。批次结束后检查有效区间覆盖、重叠、版本闭合与金额守恒。

发布和消费端要防止视图误用

数据目录为每个时态视图提供定义、默认 system cutoff 和适用场景。财务关账默认原发布,运营诊断可选择最新重述;API 请求必须显式传 temporal_mode,避免客户端升级后默认含义改变。

缓存键包含 valid 查询时点、system cutoff 与 release_id。否则旧发布可能命中新重述缓存。导出文件在页眉记录双时间边界和版本,使离线文件仍能解释。

双时态查询需要标准模板

建立四类受测模板:当前有效且当前已知、指定业务时点的最新重述、指定系统时点当时所知、两个发布版本差异。模板封装半开区间、时区和软删除规则,业务指标不允许复制自定义条件。

对事实与维度的双时态 Join,先固定事实的业务时点与发布系统时点,再选择唯一维度版本。结果输出 valid_at、known_at 与 release_id。若任何键命中多行,查询失败并进入质量告警,而不是用 row_number 随机取一条。

数据目录提供示例问题和反例,代码评审检查 temporal_mode。日常监控统计重叠命中、零命中、迟到修正和跨关闭期重述,防止模型上线后逐渐退化。

BuildTable.ai 边界

先在一个追溯频繁且审计价值高的实体试点,冻结区间规则,回放历史,发布原始与重述视图,再扩展。监控区间重叠、迟到量、重述影响和无理由修正。

BuildTable.ai 可作为双时态表和结果视图设计候选,但本文不证明当前版本自动切分区间、管理发布快照或执行法规删除。连接、调度、约束与审批需逐项核验。

公开参考资料

开始构建 AI 友好的数据基础

联系我们讨论企业数据建模场景并获取 BuildTable Desktop。

联系我们