首页/数据/数据工程与 ETL 速查/缓慢变化维 Type 3:保留前值列

缓慢变化维 Type 3:保留前值列

Type 3 在维度表增加上一版本列(如 current_level 与 previous_level),只保留有限的变更历史;结构简单、查询不用处理区间,但可记录的版本数固定。

Type 3 是什么

缓慢变化维 Type 3 在维度表里额外增加列来保存上一个版本的值(例如 current_level 与 previous_level,并可加一个变更日期列),因此只能记录有限的变更历史——常见做法就是只保留上一版。它的优点是结构简单、查询时不用处理时间区间条件,直接比较两列即可回答“等级有没有变”。缺点是历史深度固定:想记录更多版本只能不断加列,方向不对,那时应改用保留完整区间历史的 Type 2 方案。

基本信息

做法增加前值与变更日期列,更新时把旧值挪到前值列
历史深度固定列数,通常只保留上一版
查询方式直接比较当前列与前值列,无需时间区间
适用场景只做前后对比、不需要完整历史的简单分析
升级路径需要更多版本时切换到保留区间历史的方案

典型使用场景

  • 会员等级变动:需要知道本次是否升级,但不关心更早的历史
  • 价格带调整:对比调整前后的商品价格带归属变化
  • 组织架构微调:确认某部门是否在最近一次调整中换了上级
  • 客户经理变更:只关注最近一次交接,用于短期跟进
  • 状态类属性:例如从试用转正式,只保留转换前后状态

前后值列

前后值列
-- 先加前值列与变更日期列
ALTER TABLE dim_user ADD COLUMNS (prev_level STRING, level_changed_date STRING);

-- 更新:旧值挪到前值列,新值写入当前列,同时记录变更日期
UPDATE dim_user
SET prev_level = level,
    level = 'gold',
    level_changed_date = '2026-10-11'
WHERE user_id = 10086 AND level <> 'gold';

-- 查询:找出本次发生等级变化的用户
SELECT user_id, prev_level, level, level_changed_date
FROM dim_user WHERE prev_level IS NOT NULL AND prev_level <> level;

三种方式对照

方式历史深度查询复杂度适用
Type 1 覆盖无低纠错类属性
Type 3 前值列仅上一版低,直接比较列只需前后对比
Type 2 区间行完整历史中,需处理时间区间等级、组织等分析属性
需要更多历史版本时 Type 3 只能不断加列,方向不对;那种需求应该在建模阶段就选保留区间历史的方案。
前值与当前值更新不同步会留下“前后值相同”的中间态:更新语句必须把两个字段写在同一句里,避免分两次提交。
Type 3 的属性参与历史报表时仍会改变历史口径:报表按当前列分组,去年的数据会跟着今天的属性走,这一点要在口径文档里说明。

易错点

  • 用 Type 3 承载多版本历史,列数不断增加,表结构与下游 SQL 都难以维护
  • 前值与当前值分两次更新,出现前后值相同或前值为空的中间态
  • 拿 Type 3 的属性去复算历史指标,历史口径被当前值改写却无人发现
  • 把只保留上一版的限制写进口径文档之外,业务方以为能看到完整变更轨迹

数据来源与参考

  • Kimball《The Data Warehouse Toolkit》SCD Type 3
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌