CodeWalk

缓慢变化维SCD Type1/2/3实现方案

作者:屠龙少年 · 2026-05-30 12:55

请说明数据仓库中缓慢变化维(Slowly Changing Dimension)的Type1/2/3三种策略的原理、适用场景以及在大数据环境下的实现方式。

回答

屠龙少年

SCD背景: 维度表中属性随时间缓慢变化(如用户地址、产品分类),需要选择合适的处理策略。

Type1—覆写:

原理: 直接更新原记录,不保留历史

UPDATE dim_user SET address = 'New' WHERE user_id = 123;

特点:

  • 简单,无历史追踪
  • 历史数据丢失
  • 适用于:错误修正、不重要属性

Type2—增加新行(保留全历史):

原理: 变化时插入新行,用生效/失效时间标记版本

-- 旧行失效
UPDATE dim_user SET end_date = '2025-05-25' 
WHERE user_id = 123 AND end_date = '9999-12-31';
-- 插入新行
INSERT INTO dim_user VALUES (123, 'NewAddr', '2025-05-25', '9999-12-31', 2);

字段: start_date, end_date, is_currentversion

特点:

  • 保留完整历史,可回溯到任意时间
  • 数据量膨胀(每条变更产生新行)
  • 适用于:地址变迁、职位变动、产品重分类

大数据实现(Hive/Spark):

MERGE INTO dim_user t
USING (SELECT 123 as id, 'NewAddr' as addr) s
ON t.user_id = s.id AND t.is_current = 'Y'
WHEN MATCHED THEN UPDATE SET end_date = current_date, is_current = 'N'
WHEN NOT MATCHED THEN INSERT ...
-- Hive 3.x+ ACID支持MERGE

Type3—增加新列(有限历史):

原理: 保留前一个值,在原行增加列

ALTER TABLE dim_user ADD COLUMN prev_address STRING;
UPDATE dim_user SET prev_address = address, address = 'New' WHERE user_id=123;

特点:

  • 只保留上一次变化,历史有限
  • 结构变化频繁
  • 适用于:只有当前和上一个值有用的场景

选型建议:

  • 不需要历史→Type1
  • 需完整历史审计→Type2(最常用)
  • 需快速访问上一次值→Type3