数据仓库中的事实表总是在变化中,通常是新的业务数据不断装载到DW。事实表数据的增加是正常现象,也无需特别处理。但很多时候维度表的数据也会发生变化,且维度表的数据变化会导致维度表和事实表的关系发生了变化。
那什么是缓慢变化维?大概意思就是数据会发生缓慢变化的维度叫缓慢变化维,是维度,维度,维度表。所以合理处理缓慢变化维也是数仓中模型设计比较关键的。
举个栗子:
每个公司都会有销售人员或者是市场推广人员。在数据仓库中,事实表记录着业务人员的销售记录,维度表更新着业务人员的最新信息。假如一天,小王从北京调到上海开展业务,那么他以后的业绩肯定是算到上海区域了,但是调离前的业绩还是要算到北京的,这个变化怎么处理比较合适呢?这就涉及到缓慢变化维这个概念了。
通用的几种方法:
一. 新数据覆盖旧数据
前提是这个变化是公司不care的,或者是对业务人员没有影响的。公司统计的是全国业绩,业务人员去到哪里都一样,那新数据直接覆盖旧数据就可以了。
二. 保存多条记录,并添加字段加以区分
这种情况就是插入新的一条记录,同时保留原有的数据,并用单独的字段保存区别。如:
以上是添加新版本数据和新旧数据的标识,所有旧维度都把disable置为0,这样能保存所有的变化记录。
下面一种则是添加记录的生效日期和失效日期来标识新旧数据。
这种就是可以查到具体时间内业务员工作的区域了,还能通过end_date=30000000来刷选上图disable=1的数据。
三. 不同字段保存不同值
这种就是你要肯定以及保证维度数据只会更改一次,否则这么设计太蠢了。比如性别,谁还能变化两次,那这样设计就当然ok。既然这么说,实际中还真遇到了这种事!但话又说回来,谁能保证哪个字段会有变化呢,这种设计也只能存在想法中吧。
四. 另外建表保存历史记录
也就是说建一个历史表来保存变化的历史记录,而线上的维度表只保存当前数据。
这种方法想想也不方便,使用其起来还要去关联,不方便做统计。pass掉。
五. 混合模式
混合体,更全面,更能应对错综复杂且易变得用户需求,比较常用。
这种方法有几种优点:
- 能用简单的过滤条件选出维度当前的值。
- 能较容易的关联出历史任意一时刻事实数据的值。
- 如果事实表中有一些时间字段(如:order_date, pay_date, login_date),那么我们很容易选择哪一条维度数据进行关联分析。
六. 非常规混合模式
想到第六种方法是因为第五种方法有个弊端,就是维度表每个业务员都会有一个uuid,唯一且不变的。那就导致和事实表关联时是多对多的关系。这种关系不能在建模时解决,只能在报表层面,在报表运行时解决,且在BI语意层建模时需要添加时间过滤条件,比较繁琐。
那这种设计的本质就是维表里添加一个字段version_num,递增,来标注版本号,而当前最新数据version_num永远为0。
事实表中插入数据时所有的维度数据版本号也始终全部为0。
因此这种方案完全可解决事实表和维表多对多关系问题,另外还有个优点是能保证事实表和维表的参照完整性,而且我们在用ERwin,PowerDesigner等建模工具建模时,version_num和uuid可作为复合主键在两实体间建立链接。灵活运用。