缓慢变化维
这个应该是知名度最高的,天辰苹果版APP下载 “缓慢变化”也是经常会被提起的一个场景。随着时间的变化,有一些维度是会变的,就像商品维度,经常有新商品上架,有商品下架,所以要看某一天在线的商品,就需要用缓慢变化维的方式来处理。
反映历史变化也是数仓的特性之一,为了应对这种变化,有几种处理方式:
重写维度值
如果我不关心历史数据,当属性变化了,那我就看最新的数据,不管历史是什么的话,我就可以直接去更新维度数据。
比如商品A,它原来叫矿泉水,后来改成矿物质水,直接更新就好了,这时候维度表会只存有一份最新的数据。
插入新的维度行
当我们需要关注维度的历史数据的时候,天辰苹果版APP下载 我们就不能采取直接更新的方式了,我们可以通过新增记录的方式来解决,这样老的数据还在,新的数据也有。
这里要注意的是唯一建的问题,业务系统在更新维度信息的时候,很可能是直接更新掉,数仓中需要维护历史数据,所以在新增记录的时候如果没有代理键,要注意key值的唯一性,这种方法一般是需要代理键的,像上面说的商品修改名称,商品的业务key可能还是101,但是数仓中需要使用代理键来保证key值一致,但是代理键不同,这样才可以让事实表中的数据老数据使用老的代理键,新数据使用新的代理键。
这种方式也会有些问题,就是单独来看维度数据的话,同一个商品会有多条记录,会产生歧义;还有一点就是从维度表中可能看不出来记录的变化过程,并不清楚某一天该商品到底是哪一条记录为准,因为变化的特征都在事实表中。
添加维度列
这个算是一种延伸的方法,类似方法一,为了让方法一可以存历史数据,除了新增记录(纵向),还可以采用横向的方式,就是新增字段(列),来记录变化前的记录,这样通过一条记录,就可以记录商品变化前和变化后的数据了。
这样可以保证key值唯一,但是缺点也显而易见,只能记录有限次数的变化,而且要提前规划好,保留几次历史记录。
拉链表
还有一种常用的方式是拉链表,这种方式类似第2种方法,算是拓展版,也有点儿麻烦,简单来说,就是需要新增两个字段,start_date,end_date,用来记录这条就的有效周期,从哪一天开始,哪一天结束,使用的时候用这两个字段一过滤就好了。
在实际应用时,还是要考虑业务场景,根据实际情况选择,当然还有其他的方式,同样后面会再更新。
快照维度
上面说到了代理键,这个东西是很复杂的,按照维度建模的理论来,是需要搞一套代理键的,而实际操作起来会增加复杂度和维护成本,阿里采用的这种快照方式,也可以解决缓慢变化的问题。
以商品维度为例,就是每天都对商品维度生成一个快照,这样每天的商品信息都有了,key值也是唯一的,我想要看哪天的记录就看哪天,而且非常简单,使用也方便,就当前存储价格很便宜,这种方法最实用,当前公司也是使用这种方式,每天搞个分区,全量的快照,想用最新的就用最新的,想用历史的就用历史的。
当然它的缺点也明显,就是时间久了,历史数据非常庞大,有一定的存储浪费,需要注意对历史数据归档或清理。
极限存储
这个应该是阿里自己的一套实践方案,上面拉链表的方式,有几个缺点,一个是下游用户理解起来会稍有问题,需要一些解释成本,还有一个是使用start_date和end_date做分区的话,会有分区数量的限制,为了解决这些问题,阿里使用极限存储的方式来解决。
首先是在拉链表上层做了一层处理,让下游使用起来和每天一个快照的方式一样,方便使用;
然后是分月做历史拉链表,我感觉书上这里写的有点儿问题,或者是我还没理解,详情看看书吧。
网友回应