数据仓库:缓慢变化维度(SCD)

什么是SCD

SCD(Slowly Changing Dimensions),一般翻译成:缓慢变化维。

SCD的提出是因为,在现实世界中,维度的属性并不是静态的,它会随着时间的流逝发生缓慢的变化。

缓慢变化维度其实就是指,在维度表中那些会随着时间变化的字段,比如用户基本资料。

缓慢是一个相对的概念,与缓慢变化的维度相比,数据增长快速是事实表。

如何处理SCD问题

处理方法通常有3种,假设有如下的表数据:

id name city
1001 tom Shanghai

现在tom被调到北京总部工作,所以需要对city进行更新。

直接覆盖原值

对其相应的需要重写的维度行中的旧值,以当前值替换。

id name city
1001 tom Beijing

这样处理,易于实现,始终反映最近的情况,但是没有保留历史数据,无法分析历史变化信息。

增加维度行

当有维度属性发生变化时,生成一条新的维度记录,如下:

id name city
1001 tom Shanghai
1001 tom Beijing

但是这样,当与别的表通过id关联时,有两个1001的id数据,这样是有问题的,这时就需要代理键的支持(Surrogate Key,唯一标识数据仓库表记录的键)。

sk_id id name city
0001 1001 tom Shanghai
0002 1001 tom Beijing

现在每条数据都唯一,但又有一个问题,现在不知道哪条是当前在用的数据,虽然可以通过代理键找最大的(主键往往是自增的,最大的通常是最新的数据),但某些情况下要查找历史数据就不好找了,所以在维度表中加入时间字段,用NULL来标识哪条是当前最新数据,有变化再进行更新。

sk_id id name city start_time end_time
0001 1001 tom Shanghai 2016/10/26 2018/01/21
0002 1001 tom Beijing 2018/01/21 NULL

以上其实就是拉链表的典型实现,可以记录缓慢变化维度属性的变化,是一种非常有效的工具。

增加属性列

尽管第二种方式可以区分历史情况,但是无法保证能够将新属性值和过去的历史事实关联。

第三方式:增加属性列,比较适合需要根据先后顺序来得出某种结论的场景。

id name curr_city old_city
1001 tom Beijing Shanghai

这种方式的优点是,可以同时分析当前及前一次变化的属性值;缺点是,只保留了最后一次变化信息。

这种方案,在一些场景中可以解决很多问题,但我们不能无限制地添加新的字段来记录历史的状态,因此在使用这种方案时,会有一些取舍。

总结:在实际建模中,我们可以结合使用三种方式,也可以对一个维度表中的不同属性使用不同的方式。这些都是需要根据实际情况来决定,但目的都是一样的,就是能够方便的支持分析历史变化情况。

Author: VinxC
Link: https://vinxikk.github.io/2019/01/21/datawarehouse/dw-scd/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.