类型 6 是什么
类型 6 是类型 1、2、3 的组合:既保留类型 2 的历史版本行,又在同一行上维护「当前值列」和「前值列」,并用类型 1 的方式把当前值覆盖到该实体的所有历史行。于是同一属性有两套读法:按历史行读是「当时口径」,按当前值列读是「用现在的属性回溯历史行为」。它解决同一份事实需要两种归因口径的问题,代价是维护与文档成本明显上升。
基本信息
| 结构 | 历史版本行 + 当前值列 + 前值列 |
|---|---|
| 更新方式 | 新增版本行时同步把当前值覆盖到全历史行 |
| 两种口径 | 历史行属性为当时口径;当前值列为现行口径 |
| 适用动机 | 同一事实需要按当时与按现在两种方式归因 |
| 成本 | 维护、存储与文档成本显著高于类型 2 |
典型使用场景
- 按当前属性看历史:把老客户按现在的等级重新分组,分析历史消费行为
- 按当时属性看当时:同一份事实用历史行取当时等级,做当时口径统计
- 迁移分析:等级调整前后对比,前值列可直接读取变化
- 口径切换过渡期:新旧口径并存期间同时提供两套读法,报表不中断
- 分层策略复盘:current 列做现行分组,hist 列核对历史归属是否正确
- 监管对比:既要按报送时点的口径,也要按最新归类的口径出数
当前值列回写
当前值列回写
-- 第 1 步:新增版本行(类型 2 的处理)
INSERT INTO dim_user (user_sk, user_id, tier, tier_prev, tier_cur,
start_dt, end_dt, is_current)
SELECT next_sk(), user_id, 'GOLD', tier, 'GOLD',
current_date, '9999-12-31', 1
FROM dim_user WHERE user_id = 'U10086' AND is_current = 1;
-- 第 2 步:关闭旧行
UPDATE dim_user SET end_dt = current_date - 1, is_current = 0
WHERE user_id = 'U10086' AND is_current = 1 AND tier <> 'GOLD';
-- 第 3 步:类型 1 回写,把当前值覆盖到该用户的全历史行
UPDATE dim_user SET tier_cur = 'GOLD' WHERE user_id = 'U10086';三列读法
| 列 | 含义 | 适用口径 |
|---|---|---|
| tier(行值) | 该版本生效期间的属性值 | 当时口径:事实按发生时的属性归因 |
| tier_cur | 当前最新值,覆盖到所有历史行 | 现行口径:用现在的属性回溯历史 |
| tier_prev | 上一个版本的值 | 变化对比:直接看从哪一档迁到哪一档 |
| start_dt / end_dt | 版本生效区间 | 时点查询与有效期校验 |
| is_current | 是否当前版本行 | 定位最新行,唯一性必须校验 |
类型 6 最大的风险不是实现,而是两套口径混用:同一个字段名在不同报表里读法不同,数字必然矛盾。字段名要体现口径(tier 与 tier_cur),指标注释与报表标题都要标明采用哪一种,否则维护几年后没人能解释差异。