首页/数据/数据工程与 ETL 速查/缓慢变化维 Type 1:直接覆盖

缓慢变化维 Type 1:直接覆盖

Type 1 用最新值覆盖旧值,不保留历史;实现简单、维度表不膨胀,但历史指标失去当时口径,适合纠错类变更或本身无分析价值的属性。

Type 1 是什么

缓慢变化维 Type 1 指维度属性发生变化时直接用最新值覆盖旧值,维度表里只有一份当前状态,不保留任何历史。它实现最简单、维度表体积不膨胀,代价是过去的事实再也无法按“当时的口径”分析:去年那条事实行会跟着今天的属性一起变。Kimball 建议把 Type 1 用在纠错类变更(错别字、编码录入错误)或本身不具备分析价值的属性上,而把等级、组织、价格带这类会参与历史分析的属性交给保留历史的方式处理。

基本信息

更新方式UPDATE 或 MERGE 覆盖属性值
历史保留不保留
实现与存储成本低,维度表不增长
适用属性纠错类字段、无历史分析价值的属性
不适用会员等级、所属组织、价格带等分析属性

典型使用场景

  • 修正录入错误:客户名称错别字、门店名称变更后的更正
  • 补全缺失属性:首次接入时未采集的城市、行业字段
  • 上游系统改了编码规则,需要按新编码统一覆盖历史值
  • 非分析性字段的同步:联系电话、备注等不参与历史口径计算的属性
  • 主数据统一:把多个来源的同义属性合并到唯一取值

覆盖更新

覆盖更新
-- 增量批次先落到临时表,再 MERGE 进维度
MERGE INTO dim_user t
USING stg_user s
ON t.user_id = s.user_id
WHEN MATCHED AND t.user_name <> s.user_name THEN
  UPDATE SET t.user_name = s.user_name, t.update_time = CURRENT_TIMESTAMP()
WHEN NOT MATCHED THEN
  INSERT (user_sk, user_id, user_name, city, level)
  VALUES (s.user_sk, s.user_id, s.user_name, s.city, s.level);

三种处理方式对照

方式历史保留维度表增长适用
Type 1 覆盖无不增长纠错类属性
Type 2 新增行完整区间历史随变更增长等级、组织等分析属性
Type 3 前值列仅上一版列数固定增加只做前后对比
覆盖之后无法回答“去年这位用户是什么等级”,涉及等级、组织、价格带等会进入报表口径的属性时必须谨慎,先确认下游是否按当时口径复算过历史。
Type 1 覆盖不会改变代理键,历史事实行仍然指得通;代价是同一份历史数据在两次查询中会得到不同结果,因此口径文档里要写明该属性属于覆盖型。
MERGE 的匹配条件必须是维度表的业务唯一键,且临时表内部需先按该键去重;否则同一次加载会让同一实体产生多行,维度表从此出现重复。

易错点

  • 把会员等级这类分析属性做成 Type 1,历史报表口径被无声改写,复盘时找不到当时的取值
  • MERGE 匹配前未对暂存表按业务键去重,同一实体写入多行,下游连接出现重复统计
  • 覆盖时没有更新 update_time 或变更来源,事后无法判断该属性何时被谁改过
  • 把覆盖型属性与保留历史型属性混在同一张维度表里又不出文档,使用者分不清哪些能回溯

数据来源与参考

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