首页/数据/数仓建模速查/SCD 加载的幂等与重跑
维度与事实设计149 条

SCD 加载的幂等与重跑

重跑安全的关键是给本批产生的版本打批次标记:重跑时先删除该批次版本,再回滚本批关闭的旧版本,然后重新执行。

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

重跑安全靠批次标记

SCD 加载要支持重跑:同一天任务失败后重跑,结果必须与第一次成功执行完全一致。关键做法是给本批产生的版本打上批次标记,重跑时先删除该批次写入的版本,再回滚本批关闭掉的旧版本区间,然后重新执行合并逻辑。

基本信息

批次标记batch_id 或 load_ts 审计列写在维度表上
重跑步骤删本批新版本、回滚本批关闭动作、重新执行合并
验证方式区间连续性检查与每键单当前行检查
无标记代价只能全量重建,代价高且影响下游
平台差异Hive 按分区覆盖,Doris 按唯一键 upsert

典型使用场景

  • 任务失败重跑:同一天多次执行结果保持一致
  • 口径修复:修正合并逻辑后重跑历史批次
  • 补数操作:窗口合并后按批次重放
  • 上线回滚:新逻辑有问题时回滚到上一批次结果
  • 审计核对:按批次标记追溯某天的维度变更来源

按批次清理与重放

按批次清理与重放
-- 重跑:先清理本批写入的版本,再重放合并逻辑
DELETE FROM dim_customer WHERE batch_id = :batch_id;

-- 回滚本批关闭动作:把被本批关闭且实际仍生效的区间打开
-- UPDATE dim_customer
-- SET end_date = '9999-12-31', is_current = 1
-- WHERE batch_id = :batch_id AND close_reason = 'batch';

-- 重放后校验:每个自然键只能有一个当前行
-- SELECT customer_id, count(1) FROM dim_customer
-- WHERE is_current = 1 GROUP BY customer_id HAVING count(1) > 1;

重跑四阶段

阶段动作校验点
清理删除本批新版本行数回到批次执行前
回滚恢复本批关闭的旧区间每个键都存在当前行
重放重新执行合并逻辑结果与首次执行一致
验证区间连续性检查区间无重叠、无空洞
没有批次标记时只能全量重建:不仅耗时长,重建期间下游还会读到不一致的中间状态,因此批次列应当在建表时就加上。
重跑要同时恢复被关闭的旧区间:只删新版本而不回滚关闭动作,会出现没有任何当前行的自然键,下游关联时直接丢行。

易错点

  • 没有批次标记:重跑后新旧版本区间不连续,只能全量重建
  • 只删新版本不回滚关闭动作:部分自然键失去当前行
  • 重跑期间下游照常消费:读到中间状态,报表出现瞬时异常
  • 重跑与首次执行逻辑不同:结果不一致且难以比对
  • 批次列不参与分区或索引:清理操作退化成全表扫描

数据来源与参考

  • 数仓工程实践:幂等加载
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌