1. SCD 概念与背景:什么是缓慢变化维、为什么需要处理 SCD、SCD 在数据仓库中的位置

1.1 什么是缓慢变化维?

先问大家一个问题:你公司的「客户」维度表,今天和昨天一样吗?

大概率不一样。客户会换手机号、改收货地址、公司名称变更、甚至婚姻状态都会变。这些变化,就是维度属性的变化。

那什么叫「缓慢变化维」?说白了,就是维度表中的数据,变化频率不高,但确实在变。它不像销售订单那样每秒都在产生,也不像产品目录那样几年不变。它处于中间地带——今天改个地址,明天换个电话,后天升个会员等级。

我个人的定义更直白:SCD 就是处理「维度属性变了,但历史数据怎么对齐」的那套方法论。

举个例子。你去年统计华东区销售额,客户「张三」当时在上海。今年张三搬到了北京,你把他地址改了。那去年的报表里,张三的销售额算华东还是华北?

这个问题,就是 SCD 要解决的。

核心定义:缓慢变化维(Slowly Changing Dimension, SCD)是指在数据仓库中,维度属性随时间发生非频繁、非规律性变化时,如何保持历史数据一致性与可追溯性的一系列处理策略。

1.2 为什么需要处理 SCD?

不处理行不行?

行,但后果很严重。我在项目中遇到过真实案例:某电商公司做用户生命周期分析,发现去年复购率突然暴跌。查了半天,原来是用户等级字段被直接覆盖了——去年还是「黄金会员」的用户,今年全变成了「钻石会员」。历史报表全乱了。

这就是典型的直接覆盖陷阱。你改了一个字段,所有历史数据跟着「穿越」了。

处理 SCD 的必要性,我总结为三点:

  • 历史报表准确性:去年的销售额不能因为今天的地址变更而改变归属地
  • 趋势分析可信度:用户等级变化、产品分类调整,必须能回溯到变化发生的时间点
  • 审计与合规要求:金融、医疗等行业,监管要求保留完整的历史变更记录

你想想看,如果老板问你:「去年华东区业绩为什么下滑?」你总不能说「因为客户搬家了」吧?

避坑指南:我曾经接手过一个项目,上游业务系统每天全量覆盖维度表。结果做年度同比分析时,去年有 30% 的客户「凭空消失」了——因为他们的信息被新数据覆盖了。记住:维度表不是缓存,不能随便覆盖。

1.3 SCD 在数据仓库中的位置

数据仓库的经典架构,大家应该都熟悉:

  • ODS(操作数据存储):贴源层,跟业务系统长得一样
  • DWD(明细数据层):清洗、去重、标准化后的明细数据
  • DWS(汇总数据层):按主题汇总的宽表
  • ADS(应用数据层):面向报表和应用的轻度汇总

那 SCD 处理发生在哪一层?

我个人习惯放在 DWD 层。原因很简单:ODS 层要保持跟源系统一致,不能动;DWS 层已经聚合了,改起来成本太高。DWD 层是「清洗加工」的地方,正好做维度处理。

具体来说,SCD 处理涉及两个核心组件:

组件 位置 职责
维度表 DWD 层 存储维度属性,支持历史版本管理
事实表 DWD 层 通过代理键关联维度表,记录业务事件
ETL 处理逻辑 DWD 层加工过程 检测变化、生成新版本、更新有效期

这里有个关键点:代理键。业务主键(比如客户ID)不能作为维度表的主键,因为同一个客户会有多个版本。我们需要一个自增的、无业务含义的代理键来区分不同版本。

下面这张图,展示了 SCD 在整个数据仓库架构中的位置:

SCD 在数据仓库架构中的位置 ODS 层(贴源数据) 业务系统原始数据,不做任何修改 DWD 层(明细数据层)← SCD 处理发生在这里 维度表 客户/产品/时间... 含代理键 + 有效期 事实表 销售/订单/日志... 通过代理键关联维度 代理键关联 ETL 检测变化 → 生成新版本 DWS 层(汇总数据层) 按主题汇总,维度已固化 ADS 层(应用数据层)→ 报表 / BI / 数据产品 ⚠ 不要在这里改维度 保持原始数据不变 ✅ 维度已固化 直接使用代理键关联

从这张图可以看得很清楚:SCD 处理是 DWD 层的核心职责之一。ODS 层不动,DWS/ADS 层直接用处理好的结果。所以,维度建模的质量,很大程度上取决于 SCD 策略选得好不好。

1.4 什么时候不需要 SCD?

不是所有维度都需要 SCD。我个人的经验是,先问三个问题:

  1. 这个属性会变吗?——比如性别,基本不变;但年龄每年都在变,不过通常用出生日期代替
  2. 变了之后影响历史分析吗?——比如产品颜色变了,去年的销售数据需要按新颜色归类吗?
  3. 业务方接受哪种方式?——有些业务场景,直接覆盖是最简单的,只要业务方认可

举个例子。产品「重量」这个属性,如果只是内部参考,变了就覆盖,没人会追究。但如果是「产品分类」,变了之后所有历史报表都要重新归类,那就必须用 SCD。

我的建议:刚开始做数据仓库时,别一上来就搞 SCD Type 2。先跟业务方确认:「这个属性变了,历史数据要不要跟着变?」如果答案是「要」,再考虑用哪种 SCD 策略。否则,直接覆盖是最省事的。

1.5 本章小结

这一章我们聊了三个核心问题:

  • 什么是 SCD:维度属性随时间变化,需要一套策略来保持历史一致性
  • 为什么需要 SCD:不处理会导致历史报表失真、趋势分析不可信、审计不合规
  • SCD 在数据仓库中的位置:DWD 层,通过代理键关联维度表和事实表