ETL系列专题5——L之DimLoad

ETL系列专题5——LoadDimLoad

Warren

zqw_qw@hotmail.com

LLoad),装载,就是把准备好的数据加载到Star-SchemaKimball把这个步骤称作Delivery,这个词在软件业务中更专业,但是Load是从数据流角度的直观理解。其实笔者更喜欢Delivery这种说法,Delivery包含了除数据交付之外更多的涵义(ETL处理之后的交付物是加载了数据的多维数据模型)。使用Load只是为与之前的章节呼应。DW中的load,包括维度表的装载和事实表的装载,最终为终端用户/应用程序提供高效的数据访问基础。

维度表在DW/BI系统中的地位核心,虽然在Star-Schema中事实表位置居中,但不论从业务上分析还是技术上分析,维度表的设计和处理对DW/BI系统的影响要远远大于事实表的影响,每每维度一经确定,事实随之完成。虽然在DW/BI系统中维度表的数据量远不及事实表,但维度是数据分析的入口,为数据提供分析场景(context,有些人称为上下文,笔者更喜欢场景的叫法),没有确定场景的数据是没有意义的数据。

维度的基本结构

所有维度表都应该具有一个单字段的数值型主键,这个键值需要在ETL过程中产生,称作代理建,在实际设计时,我们习惯以Key作为后缀命名这个字段,比如DateKeyProductKeyCustomerKey……代理键通常是没有任何意义的,只是用来DW内部使用负责维度表和事实表做链接。但是,如果有机会让代理键附件一些实际意义,我们不应该放弃这样的机会,比如我们在日期维度中会使用yyyyMMdd这样的代理键,比如2013-6-18这个日期,我们会使用20130618这个数值作为代理键,而不是使用123….这样没有意义的方式处理日期维度的代理键。

所有维度都应该至少包含一个业务键值(可以是单列也可能是多列的组合),实际设计时习惯用IDCode作为字段名称的后缀,但不绝对,比如日期维度中我们很少使用DateIDDateCode,而是更多地直接用Date

代理键和业务键之间的对应关系取决于维度的类型,如果维度是静态的,不需要跟踪历史变更,即非SCD,那么代理键和业务键是1-1的关系,而如果维度是SCD那么他们的关系可能是M-1的关系。

维度除了业务键和代理键之外,还应该拥有更多的描述性属性,用以支持业务分析。这些属性可能非常多,多得可能让人吃惊,维度表拥有几十个字段并不稀奇。但是这些描述性属性应该是静态的或者是变化缓慢的。如果是变化频繁的属性,应该从技术上考虑分离出来。这里需要提及的一点主意事项:原则上数值型的信息应该被放入事实表中,这个原则在DW建模设计时可以覆盖绝大部分情况,但是也有一些数值型的描述型信息需要放置于维度表中。比如:产品的标准成本。

确定维度的粒度

维度的粒度,可以理解为维度的业务主键,由于维度信息来自多个数据源,这将可能导致使用某个数据源的主键无法定义维度的粒度。使用简单的查询来验证所选的业务键:

Select col1, col2, col3, count(1) cnt

From Extract_Table

Having count(1)  > 1

如果上述查询有数据返回,那么col1col2col3的组合不能确定维度的粒度。在此特别提醒设计者:每个维度中都应该有一条特别记录用以标识不存在的维度信息,通常我们在维度初始化时,插入代理键为-1,其他属性为Unknown的这样一条数据。

关于雪片型维度

比如产品可能有类别,如果把类别拆分出来单独一个维度表,那么产品维度和类别维度将出现一种多对一的关系。

这种模型看起来确实比较合理。但是,在DW系统中却未必是好的选择,首先该模型增加了维度之间的依赖关系,进而增加了维度处理的复杂度。比如我们需要在处理Product的维度时去做lookup操作。另外,也不利于提升DW的查询性能。

时间维度

时间维度是DW中必须拥有的维度,也是DW历史性的表述维度。这里特别强调一下时间维度,时间维度常用的是两类维度:一类是日历级别的时间维度,另一类是,更细粒度的比如精确到小时,分钟甚至秒的时间维度。

第一类时间维度,我们只要按照日历顺序处理数据并将所有维度数据放置于一个日期维度;第二类时间维度,通常不能集成到一个时间维度中,因为这样的时间维度数据过于庞大,不利于查询性能。通常的做法是将时间维度拆分为两个维度,一个是日期维度,粒度到天;另一部分是时间维度,粒度到分钟或/秒。对应fact表中会相应对应两个Key, DateKey timekey。如下图所示。

如何处理大维度

我们在DW模型设计时,应尽可能考虑缩小维度,以调高DW查询性能。大维度有两方面:列多,行多。比如上面处理时间维度的方式就是一种参考建模方法。

对于“快速变化维度”(想对于SCD而言),如果我们采用Type2处理将造成维度过快增长,影响DW性能,推荐的方式:将易变属性与想对静态的属性分离开来,建立两个表。

如何处理小维度

很多时候我们会发现在DW模型中有很多小维度,多用于查找过程,他们一般只有几行,甚至有的只有2个字段。比如交易类型,但是它又不应该和事实表统一在一起,也不是某个维度的属性。因此这种小的维度应该也必须存在。而有些小维度,比如之前提及的产品类别,这种维度可以理解维产品维中的属性,因此可以统一到产品维度中。

维度拆分问题

在多维建模过程中,我们肯能希望这种理想状态,就是维度之间是相互独立的。但实际上往往并非如此。例如:一个销售主题,产品可以在很多商店里销售,而且某些产品只能在制定的某个/某些店里面销售。这个场景下,貌似产品和商店已经存在了一定程度上依赖关系。但是如果我们建模时把商店信息统一到产品维度中,很可能会产生大问题。假设,目前在售产品有1百万种,商店数量是100个。那么最终的产品维度将有10亿条数据!这显然不是个好的建模方式。处理方法其实在之前已经提及了,就是按照时间维度的处理方式。这种方式的原理就是:把维度之间的关联在事实表中体现

但是,千万不要看到维度之间的依赖就采用上述方法把维度分解。例如,就像我们很少看到有品牌维度一样,因为品牌维度通常作为产品的一个属性。相关的维度是否合并,主要考察合并后是否造成维度过大。过大,在我们这个行业领域真的是与时间高度相关的。我曾经因为我给我的586配置了64M内存,4.3G硬盘而沾沾自喜,那是1998年。相当高的配置。所以什么样的数据量是维度表的上限,真的不好说。我在一个项目中涉及到一个维度,是一个全球在线游戏的玩家,一共1个亿玩家!User维度有1亿行数据!我真的很想把它拆分了,但是以我当时和目前的水平还没能找到好的办法来处理,但是可喜的是,我们的DW系统并没有因为这个核心的大维度而产生性能问题。原因有2个:服务器配置好,DW性能优化得好。所以笔者这里不敢给出一个具体的行数供大家参考,这个问题需要根据实际情况确定。

维度的角色扮演

有时候摸个维度可能出现在不同场合,代表的意义也不相同,最常见的就是时间维度,如果比如在销售场景下,可能有很多日期:下单日期,发货日期,退货日期,首次付款日期等等。这么多日期,我们当然不需要把做这么多个日期维度。只需要一个日期维度,通过与事实表的不同日期外键关联即可,这样日期维度就出演了不同角色。

SCD

SCD是多维建模必须考虑的维度设计,也是ETL系统必须具备的处理能力,通常有3种类型的处理方式。这里不做具体说明,google将详细介绍三种不同处理方式的实现方法。这里特别强调关于Type2维度字段的建议。建议采用Type2处理方式时,在维度表中确保有如下字段:

StartDate: 信息修改日期

EndDate:过期日,下次修改时更新

ReasonOfChange:变更说明

CurrentFlag:当前有效/失效标志

关于桥接维度

笔者更愿意称这样的维度为事实,通常这种桥接维度是为了避免事实表和维度表之间的多对多关系。桥接表的作用就是把多对多的关系,提取出来放到桥接维度中。笔者,之所以喜欢称这样的表为事实表,正是因为它描述了一个事实的关系,虽然可能没有具体的量度。

退化维度

退化维度表现为,在fact表中代表维度信息,却没有外键相关的维度表,比如在fact表里面有个OrderNumber字段,但是设计时没有与之对应的Order维表。OrderNumber即成为Order的退化维度。需要注意的是,退化维度是否参与fact粒度定义,或者说退化维度字段是否是PK的属性之一。如果它参与了粒度定义,那么可能会出现问题。我们知道理论上fact的数据粒度是所有维度的组合,即PK可以由所有FK组合而成(实践中很多情形,只要部分组合即可)。如果退化维的参与粒度定义,那么可能需要退化维度字段加入PK组合。这时需要考虑一个问题就是:这个退化维度字段信息在不同业务系统中是否有重用现象,如果可以重用,那么需要对字段取值的设计做更多考究。

维度数据迟到

这里讨论的迟到是指fact数据已经存在,但是维度的更新数据由于某种原因没有及时更新,造成DW/DM中数据不一致。比如,一个产品的型号从的有效期已经在20121231日从A修改为B,但是这个修正信息直到201321日才被抽取到DW。这就产生了一个数据问题:20121231日之后的相关fact数据的该产品型号应该是型号B,但从目前(201321日)回溯到20121231日这段时间的fact数据产品型号依然是A。该种情形需要做如下处理步骤:

1、  Type2处理产品维度,插入新数据(型号为B的数据),同时设置新数据的起始日期为2012-12-31currentflag = true

2、  设定之前产品型号为A的维度信息的结束日期(2012-12-31),currentflag=false。修改2012-12-31之后所有该产品的记录,并修改产品型号为B

3、  修改fact数据:修改2012-12-31之后的所有数据的产品外键,指向新记录的代理键。

 

上面介绍的是维度版本迟到情况。另一种维度信息迟到是真正的迟到,即处理fact数据时,维度表里根本不存在这样的维度记录,将在加载fact章节介绍。

这里思考一个问题,如何处理维度表中不需要的记录?假设源已经做了删除处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值