在做数据分析、建数据仓库的时候,你有没有遇到过这种情况:
“客户搬家了,城市字段要改;职位升了,Title 字段也要改;但我又不想把历史数据给弄丢了!”
这时候你就需要用到一个很重要的概念:SCD(Slowly Changing Dimension,慢变维)。
🧠SCD 是什么?
SCD 的意思是:维度表里的某些字段会慢慢发生变化,我们要决定怎么处理这些变化。
比如你有一个客户表,里面有客户的名字、城市、职位等信息。客户搬家了、改名字了,这些字段就变了。那你是直接改掉呢?还是保留历史记录?这就是 SCD 要解决的问题。
🧱维度表是啥?
维度表就是那种描述性的表,比如:
-
客户表(Customer) -
产品表(Product) -
员工表(Employee)
这些表里的字段通常是用来做筛选、做图表轴的,比如“按城市看销售额”、“按职位看员工人数”。
🔧SCD 有哪些类型?
SCD 一共有 7 种类型,但常用的就前面几种,下面我用口语化方式给你讲讲:
🟢Type 0:啥都不改
意思是:这个字段不能变!比如客户 ID,如果变了说明系统有问题,直接拒绝改动。
ETL 操作:啥都不用做,最简单
🟡Type 1:直接改掉
比如客户改了名字,但我们只关心最新的名字,不在乎历史记录,那就直接更新字段。
ETL 操作:UPDATE 或者 DELETE + INSERT。
很多人其实已经在用 Type 1,只是没意识到而已。
🔵Type 2:保留历史记录(最常用)
比如客户从纽约搬到伦敦,我们希望保留他在纽约时的记录,也记录他现在在伦敦的状态。
做法是:新增一条记录,加上两个字段:
FromDate:这条记录开始生效的时间ToDate:这条记录结束的时间(当前记录是 NULL)
ETL 操作:先更新旧记录的 ToDate,再插入新记录。这个过程叫 UPSERT。
🟠Type 3:只保留上一次的值
比如我们只关心客户现在和上一次的职位,不需要完整历史。
做法是:加两个字段:
-
当前值 -
上一次值
ETL 操作:把当前值移到“上一次值”字段,再更新当前值。
🟣Type 4:历史记录单独放一张表
Type 2 会让维度表越来越大,Type 4 的做法是:
-
当前值放在维度表 -
历史值放在另一张表
ETL 操作:更新维度表,同时插入历史表。
这种方式更干净,但 ETL 稍微复杂点。
⚫Type 5、6、7:混合型(了解即可)
-
Type 5:Type 4 + Type 1 -
Type 6:Type 1 + 2 + 3 -
Type 7:在事实表里同时存 Surrogate Key 和 Natural Key,方便查历史
这些类型比较复杂,实际项目里不常用,了解一下就行。
📚实际应用案例:员工职位变动追踪
假设你在一家大型制造企业工作,HR 系统里有一张员工维度表,字段包括:
-
员工编号(EmployeeID) -
姓名(Name) -
部门(Department) -
职位(Title) -
入职时间(StartDate)
现在有个业务需求:我们需要知道某个员工在不同时间段担任过哪些职位。
如果你用的是 Type 1(直接更新),那员工职位一变,原来的记录就没了,历史分析就做不了。
比如:
|
|
|
|
|---|---|---|
|
|
|
|
张三升职为“高级工程师”后,记录变成:
|
|
|
|
|---|---|---|
|
|
|
|
原来的“工程师”记录就丢了。
✅解决方案:用 Type 2(保留历史)
我们改造一下维度表,加上这些字段:
-
SurrogateKey(唯一标识每条记录) -
FromDate(这条记录开始生效的时间) -
ToDate(这条记录结束的时间)
变成这样:
|
|
|
|
|
|
|
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样你就可以:
-
查出张三在 2022 年是工程师 -
查出他在 2023 年升职了 -
做时间序列分析,比如“每年各职位人数变化”
🛠在 Microsoft Fabric 里怎么实现?
你可以用以下方式实现 Type 2:
-
用 Dataflow Gen2 或 Notebook 做 UPSERT 操作 -
把维度表存到 Lakehouse 或 Warehouse -
在 Power BI 里用 FromDate和ToDate做时间切片分析
这样既满足了业务分析的需求,又保留了完整的历史记录。
✅总结一句话
SCD 就是处理维度表字段变化的策略,决定你要不要保留历史记录。
-
Type 1:直接改 -
Type 2:保留历史 -
Type 3:只保留上一次 -
Type 4:历史单独存 -
Type 0:不改 -
Type 5/6/7:混合型
在实际项目中,Type 1 和 Type 2 是最常用的。搞清楚这些类型,你的数据仓库就能更稳、更准、更灵活!

