我回答面试官,说缓慢变化维有10种处理方式,他惊了

2,800

顾名思义,缓慢变化维(Slowly Changing Dimension)就是变化相对缓慢(相对与快速变化的事实表来说)的维度。

在维度建模理论中,有8种处理方式,包括基础的5种以及混合的3种。

再加上大数据时代的2种极限型,共10种,具体如下:

1 基础型

1.1 方式0:保留原始值

维度属性值不做更改,保留原始值。

此方式什么也不做,所以称之为方式0。

  • 比如商品上架售卖时间:一个商品上架售卖后可能由于缺货下架,补充库存后又再次上架,此种情况产生了多个商品上架售卖时间。如果重点关注的是商品首次上架售卖时间,则采用方式0。
  • 比如商品所属供应商:a商品的供应渠道是某供应商,随着时间推移可能转款到b供应商(由b供应商来供货),此种情况如果关注的是原始最初供应的供应商,则采用方式0。

1.2 方式1:直接覆盖

修改维度属性为最新值,直接覆盖,不保留历史信息。

  • 比如商品属于哪个品类:当商品品类发生变化时,直接重写为新品类,如果业务只关心最新的品类。

1.3 方式2:增加新行

在维度表中增加新的一行,新行中采用新的属性值。此种方式需要借助代理键,需要为新行分配新的代理键,将其作为事实表的外键。

采用此方式,一般会在维度行中额外增加3列:行生效时间,行失效时间以及当前行标识(或者不使用当前行标识,由行失效时间来判断是否是当前行)

此方式及其变种是处理缓慢变化维的主要技术。

比如

维度属性值变化前:

商品键(代理键) 商品唯一键(自然键) 品类 行生效时间 行失效时间 当前行标识
1 SPU001 科技 2020-01-01 9999-12-31 1

维度属性值变化后:

商品键(代理键) 商品唯一键(自然键) 品类 行生效时间 行失效时间 当前行标识
1 SPU001 科技 2020-01-01 2020-01-31 0
3 SPU001 教育 2020-02-01 9999-12-31 1

1.4 方式3:增加新属性列

在维度表中增加新的一列,原先属性列存放上一版本的属性值,当前属性列存放当前版本的属性值。

比如

维度属性值变化前:

商品唯一键 品类
SPU001 科技

维度属性值变化后:

商品唯一键 当前品类 原先品类
SPU001 教育 科技

1.5 方式4:增加微型维度

当某维表是一个大型维度表,采用方式2时,如果某些维度属性变化相对较快,会导致该维表变得越来越大,导致存储压力和性能压力。

此时引入微型维度是一个不错的选择,将某些维度属性从该大型维表中抽离出来,单独构建微型维度。

比如将用户最近消费时间、消费频率、消费金额从用户维表中剥离出来,并结合业务以区间段形式表现,单独构建成RFM微型维度,并在相关事实表中增加RFM键作为外键

RFM微型维度:

RFM键 最近一次消费 消费频率 消费金额
1 7天内 >=月均5次 >=10000
2 30天内 >=月均5次 >=10000
3 超过一个月 >=月均5次 >=10000
4 7天内 >=月均1次 >=10000
5 30天内 >=月均1次 >=10000
6 超过一个月 >=月均1次 >=10000
... ... ... ...

相关事实表:

日期键 用户键 RFM键 其他外键 事实
20200501 00001 1 XXX 10

2 混合型

2.1 方式5:微型维度与方式1支架表

该方式是方式1和方式4的结合,即建立微型维度后,微型维度的主键不仅作为事实表的外键,也作为主维度的外键。

在主维度中,此微型维度属性以方式1处理,即当该属性发生变化时,直接覆盖,不保留历史信息。

这种情况下的微型维度被称之为支架。

如方式4中的例子,我们再将RFM键添加至主维度(用户维度表)中作为外键,以方式1进行更新,即为方式5

用户维度表:

用户键 用户名称 其他属性 RFM键
00001 张三 ... 1

2.2 方式6:将方式1属性增加到方式2维度

该方式是方式1、2、3的结合,即同时增加维度行和维度列,并以方式1处理新加的维度列(当前属性)。

此种方式复杂,在少数特定迫切的场景下才会使用。

如商品的品类变化

品类变化前:

商品键(代理键) 商品唯一键(自然键) 历史品类 当前品类 行生效时间 行失效时间 当前行标识
1 SPU001 科技 科技 2020-01-01 9999-12-31 1

品类变化后:

商品键(代理键) 商品唯一键(自然键) 历史品类 当前品类 行生效时间 行失效时间 当前行标识
1 SPU001 科技 教育 2020-01-01 2020-01-31 0
14 SPU001 教育 教育 2020-02-01 9999-12-31 1

品类再度变化后:

商品键(代理键) 商品唯一键(自然键) 历史品类 当前品类 行生效时间 行失效时间 当前行标识
1 SPU001 科技 教材 2020-01-01 2020-01-31 0
14 SPU001 教育 教材 2020-02-01 2020-03-31 0
235 SPU001 教材 教材 2020-04-01 9999-12-31 1

2.3 方式7:双重外键并且方式1与方式2结合

在方式2的基础上,不仅是维度的代理键作为事实表外键,维度的自然键(如果自然键会被重新分配,发生变化,应该使用持续性超自然键)也同时作为事实表外键。

事实表通过代理键连接维表获取历史维度属性,通过自然键连接维表获取当前维度属性。

如以商品维度为例

方式2维度表(包含历史信息)

商品键(代理键) 商品唯一键(自然键) 品类 其他属性 行生效时间 行失效时间 当前行标识
1 SPU001 科技 xxx 2020-01-01 2020-01-31 0
3 SPU001 教育 xxx 2020-02-01 9999-12-31 1

相关事实表

日期键 商品键(代理键)(外键) 商品唯一键(自然键)(外键) 其他外键 事实
20200111 1 SPU001 XXX 10
20200501 3 SPU001 XXX 10

方式1维度表(当前信息)(可以基于方式2维度表建立视图形式产生,筛选当前行标识=1的记录即为当前信息)

商品唯一键(自然键) 当前品类 其他属性
SPU001 教育 xxx

3 极限型

3.1 方式8:快照维度

此种方式比较暴力,每天保留全量维度属性的快照数据,自然键及日期键作为事实表的外键。

此方式依托的是当前存储成本远低于计算成本,以空间换时间的理念。

如商品快照维度表

日期键 商品唯一键(自然键) 品类 其他属性
20200101 SPU001 科技 xxx
20200102 SPU001 科技 xxx
... ... ... ...
20200201 SPU001 教育 xxx
... ... ... ...
20200501 SPU001 教材 xxx

3.2 方式9:历史拉链维度

此方式是方式2的阉割版,同样是增加维度行。

但舍弃了代理键,因为如MapReduce之类的分布式计算引擎,维护全局唯一的代理键难度大,成本高。

优点是此方式相比方式8,大大降低了存储(当然前提是不包含变化频率很高的维度属性,如果有,请考虑进行垂直拆分)。

缺点是和事实表连接时会有一些不足。如事实表只能以时间切片的方式和维度表进行连接,如果事实表要多个时间切片同时与维度表关联,需要一定的技术改造。

商品唯一键(自然键) 品类 行生效时间 行失效时间
SPU001 科技 2020-01-01 2020-01-31
SPU001 教育 2020-02-01 9999-12-31

4 结语

以上就是针对缓慢变化维的10种处理方式了。

随着数据技术的发展,维度建模方法也不是一成不变的,需要结合当前技术的特点进行灵活转变。

总之,没有最牛x的建模方法论,只有最适合的。