一开始看到这个词的时候给我的第一印象就是拉链表,缓慢变化表拥有从表创建开始到现在的所有数据,包括状态变化的数据。
那么什么是缓慢变化表呢?
首先要来了解一下什么是缓慢变化维,就是在业务进行过程中,会发生变化,但又不会频繁变化的维度。
假如现在有一张员工表,里面有A,B,C三位员工,里面纪录了员工的一些基本信息,例如工作地点,职级,员工id等信息。
员工id | 员工名 | 工作地点 | 职级 |
---|---|---|---|
001 | A | 北京 | 普通员工 |
002 | B | 上海 | 普通员工 |
003 | C | 长沙 | 普通员工 |
那么有一天,B员工因为岗位调动,需要将工作地点变更到北京,应该怎么进行处理呢?
目前来说一共有三种处理方法。
1.直接在原表的记录上来更新,将B的工作地点更新为北京。
员工id | 员工名 | 工作地点 | 职级 |
---|---|---|---|
001 | A | 北京 | 普通员工 |
002 | B | 普通员工 | |
003 | C | 长沙 | 普通员工 |
这样虽然记录变更过来了,但是存在一些问题。假如说B是2019年7月4号把工作地点变更为北京,那么他之前在上海的业绩应该怎么算呢?在统计业绩的时候,这种方式能关联到的只有B在北京的信息,那么这些业绩都纪录在北京吗?实际上B的7月份以前的销售数据均应算在上海。
那么这种问题应该怎么解决呢?引出了方法2
2.在保留历史纪录的情况下,在原表中添加一条记录,将B的工作地点更换为北京。
员工id | 员工名 | 工作地点 | 职级 |
---|---|---|---|
001 | A | 北京 | 普通员工 |
002 | B | 上海 | 普通员工 |
003 | C | 长沙 | 普通员工 |
002 | B | 北京 | 普通员工 |
如果是这样的话,在进行关联的时候,对于B来说会关联到两条纪录,这样在后续计算中是不正确的,B怎么能在同一时间存在两条有效的岗位纪录呢?
对于这种情况,有以下几种解决办法
①加一个代理键,这个代理键随着纪录的增加其序号自然递增,这样最新的纪录总是代理键最大的。对于B来说,会增加一条代理键为4的纪录,如下图所示:
代理键 | 员工id | 员工名 | 工作地点 | 职级 |
---|---|---|---|---|
1 | 001 | A | 北京 | 普通员工 |
2 | 002 | B | 上海 | 普通员工 |
3 | 003 | C | 长沙 | 普通员工 |
4 | 002 | B | 北京 | 普通员工 |
在和这张表进行关联的时候,对于B这种拥有多条记录的员工,可以根据代理键进行区分。
②但是这样也有一个问题,就是这张员工表里面没有岗位变化的时间,它只能区分哪条是最新的岗位纪录,当有需求需要插入历史业绩纪录的时候,无法知道这条纪录属于B在上海的业绩还是B在北京的业绩,所以一般都用两个时间字段来进行处理,一个是岗位开始时间,一个是岗位结束时间,如果岗位没有变更,那么其结束时间就是一个极大值。如下图所示:
员工id | 员工名 | 工作地点 | 职级 | 岗位开始时间 | 岗位结束时间 |
---|---|---|---|---|---|
001 | A | 北京 | 普通员工 | 2015-03-02 | 9999-99-99 |
002 | B | 上海 | 普通员工 | 2015-06-04 | 2019-07-04 |
003 | C | 长沙 | 普通员工 | 2014-07-28 | 9999-99-99 |
002 | B | 北京 | 普通员工 | 2019-07-05 | 9999-99-99 |
这样假如需要插入的历史数据是2019-05-21的数据,很轻易的就能判断出它是属于B在上海的业绩。
3.有时需求中并非所有字段的变化都进行记录并且不需要每次变化都记录,比如我们可能只关心工作地点的最近两次变化。
代理键 | 员工id | 员工名 | 老工作地点 | 新工作地点 | 职级 |
---|---|---|---|---|---|
1 | 001 | A | 北京 | 普通员工 | |
2 | 002 | B | 上海 | 北京 | 普通员工 |
3 | 003 | C | 长沙 | 普通员工 |
参考文章: