一.什么是缓慢变化维?
尽管维度的属性相对稳定,但他们不可能一成不变,随着时间的推移,属性值仍然会发生变化。我们必须采取对应的策略应对发生的变化。缓慢变化维度:Slowly Changing Dimension,缩写为SCD
尽管维度表属性相对稳定,但它们不可能是一成不变的,尽管相当缓慢,属性值仍会随时间发生变化。最常用的SCD为:类型1(重写)、类型2(增加新行)、类型3(增加新属性)。
二.怎样处理缓慢变化维?
处理方法通常分为3种:
假设有这样一条数据:
id | name | department |
---|---|---|
101 | zhangsan | A |
现在zhangsan离开A,前往B部门工作,所以需要对department数据进行更新
第一种:直接覆盖原值
id | name | department |
---|---|---|
101 | zhangsan | B |
这样处理,最容易实现,但是没有保留历史数据,无法分析历史变化信息
第二种:添加维度行
当有维度属性发生变化时,生成一条新的维度记录,如下:
id | name | department |
---|---|---|
101 | zhangsan | A |
101 | zhangsan | B |
但是这样,当与别的表通过id关联时,有两个101的id数据,这样是有问题的;所以就需要代理键的支持。(在数据仓库的术语里面,这个唯一标识数据仓库表记录的键我们称之为 Surrogate Key 代理键)
sk_id | id | name | department |
---|---|---|---|
001 | 101 | zhangsan | A |
002 | 101 | zhangsan | B |
现在每条数据都唯一,但又一个问题,现在不知道哪个是当前在用的数据,虽然可以通过代理键找最大的(因为主键往往是自增的,最大的通常是最新的数据),但某些情况下要插入历史数据就不好找了,所以在维度表中加入时间序列,用NULL来标识哪条是当前最新数据,有变化再进行更新。
sk_id | id | name | department | start_time | end_tinme |
---|---|---|---|---|---|
001 | 101 | zhangsan | A | 2017/08/27 | 2018/06/20 |
002 | 101 | zhangsan | B | 2018/06/20 | NULL |
第三种:添加属性列
id | name | curr_department | old_department |
---|---|---|---|
101 | zhangsan | B | A |
这种方式的优点是,可以同时分析当前及前一次变化的属性值
总结:在实际建模中,我们可以联合使用三种方式,也可以对一个维度表中的不同属性使用不同的方式;