首页/数据/数仓建模速查/SCD 类型 7:历史表加当前值视图
维度与事实设计149 条

SCD 类型 7:历史表加当前值视图

主表保留类型 2 历史行,另用视图把每个自然键的当前属性覆盖到全部历史行,形成「当时口径」与「当前口径」双读出口。

数仓建模速查数据更新于 2026-10-13

类型 7 是什么

类型 7 指主表仍按类型 2 保留历史版本行,另外用一张视图把每个自然键的当前属性覆盖到它的全部历史行上。于是同一份历史数据有两个读出口:直接读主表是「当时口径」,读视图是「用当前属性回溯历史」。它与类型 6 的目标相近,区别是当前值不落在物理表里,而是由视图实时关联得出,因此不产生额外回写与存储。

基本信息

主表类型 2 的历史版本行,逐行保留当时值
视图每个自然键关联当前行,把当前属性覆盖到全部历史行
价值同源双口径切换,不增加物理存储与回写
与类型 6 差别当前值由视图计算,不回写物理列
命名要求视图名与列名都要带 hist 或 cur 前缀区分口径

典型使用场景

  • 分析口径切换:同一批历史事实既要按当时等级,也要按当前等级出数
  • 客户回溯分群:把老客户按现在的区域重算历史业绩归属
  • 审计比对:监管或内审要核对当时值与当前值的差异
  • 降低改造成本:不想回写物理列,用视图满足第二种读法
  • 报表过渡期:新旧口径并存几个月,靠双读出口让报表不中断
  • 敏感口径隔离:当前值视图单独授权,限制能看当前口径的人

当前值视图

当前值视图
-- 主表:类型 2 历史版本行(一行一个版本,含生效区间)
-- dim_customer(customer_sk, customer_id, name, tier,
--              start_date, end_date, is_current)

CREATE VIEW v_dim_customer_cur AS
SELECT h.customer_sk,
       h.name        AS hist_name,   -- 当时值
       c.name        AS cur_name,    -- 当前值
       h.tier        AS hist_tier,
       c.tier        AS cur_tier,
       h.start_date, h.end_date
FROM   dim_customer h
JOIN   dim_customer c
  ON   h.customer_id = c.customer_id
 AND   c.is_current = 1;   -- 每个自然键只有一条当前行

两个读出口

对象口径用途
dim_customer 主表当时口径按事实发生时的属性归因
v_dim_customer_cur 视图当前口径用现在的属性回溯历史行为
hist_ 前缀列当时值核对历史归属
cur_ 前缀列当前值现行分组与筛选
is_current版本定位关联当前行,需校验唯一性
类型 7 的优点是零额外存储、天然不会出现物理列回写不同步的问题;代价是每次查询都要多关联一次当前行,大表上视图的代价不可忽略,必要时物化。视图与列都必须显式标注口径,否则分析师极易拿错列。

易错点

  • 两套口径未在命名上区分:报表间结果互相矛盾,且没人能说清哪个是对的
  • 当前值列被当作历史当时值参与统计:历史归因整体偏移
  • 视图未过滤 is_current:一个自然键关联出多条当前行,行数翻倍
  • 把视图当物理表直接物化却不维护刷新频率:物化后与主表不同步,口径再次分叉
  • 当前值关联未走索引:大表点查变成全表扫描,查询超时

数据来源与参考

  • Kimball Group:缓慢变化维技术(Type 7)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌