深入解析数据仓库中的缓慢变化维

作者:无忧博主 2024-03-11 浏览:28
导读: 这样一来,因为事实表存储的是维度表的代理键而非自然键,因此在历史数据的查询中会以历史的维度值进行计算。同时在维度值更新后的相关数据自然使用的是新的代理键。...

这样一来,因为事实表存储的是维度表的代理键而非自然键,因此在历史数据的查询中会以历史的维度值进行计算。同时在维度值更新后的相关数据自然使用的是新的代理键。完美的解决了大部分缓慢变化维情况。

类型3 增加当前值属性

在大部分的维度模式中,很多的源数据变化将产生类型1和类型2变化。有时两种技术都不能满足需求——当需要分析所有 伴随着新值或旧值的变化前后 记录的事实时,需要采用类型3变化。

很多人都难以理解类型3的重要性,因此笔者举一个例子——一个无法用类型1和类型2处理的例子:

假定一家公司的销售是按照销售区域进行分组:

突然有一天,领导灵机一动,决定 精细化销售,将东部、南部、北部重新划分为东南、东北部

但由于发送的过于仓促,因此销售人员是立刻使用了新的部门划分;但同样希望保留旧的名称——至少要暂时保留,用以比较今年和去年的业绩。即:

第一个需求——新区域分析——允许立即采用新的分组,所有历史订单都能分为东南、东北等新类别;

第二个需求——旧区域分析——允许公司采用旧分组,所有的订单可以根据旧值分组——就好像一切都没发生过变化。

这时,就会发生一些问题:先前的技术不适合——无论是类型1还是类型2,都不能同时满足这两个需求;

此时引入 类型3 处理方法:新增字段同时储存新旧值。

如果发生第二次变化,当前的current会被更新到last中,新的变化值则会写入current。

类型3 不保存事实的历史内容

需要注意的是,类型3 的改变往往并不是一个仅此一次的过程——它能发生1次就有可能发生2次甚至更多次。类型3 变化只保护变化属性的一个旧版本,一旦发生第二次变化,第一次变化前的值就要被废弃了。如果想要用变化3 来实现更多的版本,那只能增加更多的列来实现(例如dpt_2018,dpt_2019)——这无疑是非常愚蠢的。因此,除非特定需要,应尽量避免使用类型3的变化。

其他类型

剩下的5种类型基本都不被采用,但值得一提。

类型0 不做调整

这里的数据定义与类型1类似,但不同点在于 类型0绝不允许ETL对该维度进行更新——你真要改的话就手动改表吧。

例如数仓中的代理键类型4 微型维度

当变化频率加快时候,并且维度表包含几百万行的维度表。如果对变化的跟踪采用可靠的SCD2技术对浏览和查询性能具有负面影响——太多行且无必要。采用新的独立的维度表消除频繁分析或者频繁变化的属性,这一维度技术叫做微型维度。

例如employee的 年龄、薪资、税收金额

年龄每年一变,薪资、税收金额也经常改变

这里要注意:

这些“易变化”的值并非存储其准确的值,而是其范围值;

例如年龄,我们不会存“23",而是会存"20-30"。收入我们不会存”999“,而是”0-1000“。如果存准确值的话,数据量会过于高。从分析角度,我们往往也只需要一个模糊的范围即可。

如果需要记录准确值,可以考虑使用 无事实的事实表 单独记录。微型维度没有自然键,只有值的笛卡尔积组合。

你不会在表中看到 user_id 这种自然键,因此类型4中微型维度只能在事实表中出现。

如果想把维度表和相关的微型维度连起来,那就是类型5了。

常见的微型维度表结构:

可以看到,该微型维度是由 年龄和薪资的笛卡尔积组合构成。

你可以在建立时就将所有可能组合都预计算存入——缺点是表一开始就较大,但优点是省去了ETL的功夫

也可以出现一个存一个,维度表的稀疏性表明了实际数据量并不会那么多。

常见的维度表、微型维度、事实表组合:查看餐饮时雇员的职位和年龄。

可以看到,微型维度表与维度表通过事实表相连,并不直接连接。类型5 类型1+微型维度

类型5,即是将类型4与类型1组合起来的方法合并。 该技术的特点是增加当前微型维度主键作为主维度的一个属性。该属性在主维度中以类型1进行变化更新——从而避免主维度表行的爆炸增长

这样一来:

可以从主维度表获取到其对应的微型维度数据——虽然只有最新的。可以从相关事实表中获取微型维度历史变更的信息。类型6 类型1+类型2+类型3

类型6,即是将类型1、2、3的联合使用。

主要解决的业务场景是:

该维度列变化频次较高,但即使这样也希望历史业务能以最新的值来分析。无法确定每次该维度的变更时间。希望保留历史数据方便追溯

下图为例:

ETL步骤:

记录需要如此处理的列,分别创建previous和current两列。新数据插入时,current = previous.该列有新值时,

类型7 双类型1+类型2

在上面的类型6有一个缺点——需要额外增加一个current列。

如果有大量的维度都需要如此处理的话就会有问题:假定该维度表有150列,如果我们都用类型6处理,则会变成300列——这无疑是令人无法接受的。

类型7就是 解决以上困难的。有很多种实现方法,下面会介绍2种比较常见的

这么一来,如果想要了解雇员在用餐发生瞬间历史的状态,关联至左边的维度表即可得知;如果想要以雇员最新的状态进行分析。则直接取右边的表即可。

转载请注明出处:无忧博主,如有疑问,请联系(762063026)。
本文地址:https://wuyouseo.com/it/2466.html