类型 3 是什么
类型 3 在同一行上增加一列保存上一版本的值,例如同时有 tier 与 previous_tier、address 与 previous_address。它的历史深度只有一跳,表宽固定、不随变更次数增长,查询时不需要过滤生效区间。适合变更很少且只关心「最近一次迁移」的场景,例如客户等级调整、地区归属变更前后对比。它无法回答「上上次是什么」,需要多跳历史时应改用类型 2 拉链。
基本信息
| 历史深度 | 仅保留上一版本,一跳 |
|---|---|
| 实现 | 增加前值列,更新时先搬再覆盖 |
| 适用 | 变更少、只关心最近一次迁移 |
| 限制 | 多次变更后旧值被覆盖,更早历史丢失 |
| 配套列 | 通常再配一列变更时间,说明前值对应何时 |
典型使用场景
- 客户等级迁移:只看从哪一档升到哪一档,用于当期营销分析
- 区域重划:行政区或销售区域调整前后对比
- 价格档位调整:只关心最近一次调价前后的档位
- 费率变更:上一次费率与当前费率对比,做差异测算
- 归属变更:客户从 A 团队转到 B 团队,看最近一次转移
- 折中方案:业务只要最近一次变化,不必为完整历史承担拉链成本
更新前值
更新前值
-- 更新前先把当前值搬到前值列,再覆盖当前值
UPDATE dim_user
SET previous_tier = tier, -- 先搬
tier = :new_tier, -- 再覆盖
changed_date = :dt
WHERE user_id = :id;
-- 查询本次迁移:前值与当前值不同的成员
SELECT user_id, previous_tier, tier, changed_date
FROM dim_user
WHERE previous_tier IS NOT NULL
AND previous_tier <> tier; -- 只看最近一次发生过变化的成员类型 3 与类型 2 对比
| 对比项 | 类型 3 | 类型 2 拉链 |
|---|---|---|
| 历史深度 | 一跳 | 完整历史 |
| 表宽与行数 | 列数固定,行数不变 | 行数随变更次数增长 |
| 查询复杂度 | 无需区间过滤 | 需按生效区间或当前标志过滤 |
| 多次变更 | 旧值被覆盖,更早历史丢失 | 逐次版本都保留 |
| 改造成本 | 加列即可 | 需要重建版本行与增量作业 |
类型 3 最常见的误判是「先按类型 3 做,将来不够用再改成类型 2」:等到需要多跳历史时,中间几次变化没有任何记录,只能回溯源系统日志,改造成本远高于一开始就选类型 2。属性如果可能被用于历史归因,就该一开始就评估这一点。