建立数据仓库

本文介绍建立维度模型的通用方法。接下来的的内容覆盖了从源系统装载数据与建立SSAS Cubes来展现数据到最终用户的详细内容

 

建立维度表

虽然在不同的业务系统中表设计存在差异,但是他们通常都遵循一定的模式。一些标准方法在建立高性能数据仓库上是通用的。

 

  1. 使用代理键  

在数据仓库中每个维度表都有一个代理键来单独标示一行维度记录。在SQLServer中,使用的是自增长列。也就意味着不必为这列指定值,当有新记录加入时数据库每次都生成一个自增长数字。

 

      2.     添加业务键

 

即用来保存数据库源中主键的列,可以为任何类型,但是一般是跟源表中主键相同类型。通常,建立此列的时候要注意使此列非空,并为此列建立唯一索引。因为我们需要使用业务键去源系统中查找记录,唯一索引将会保证没有重复值(重复值会导致查找失败)。不过在变化的维度中,唯一索引并不适用,后面详细论述。

 

     3.    为维度表添加索引

 

唯一约束加到业务键列后也会产生一个索引,我们将它设置为聚集索引。这意味着维度表中的数据将会在物理上按照业务主键的顺序进行存储,这将会提高在从维度表中使用业务键进行查找记录的性能。比如,当从源表获得一条记录时,ETL进程需要适用业务键去查找这个记录已经存在还是新增加的。

数据仓库首要的用处作为一个一致的存储来装载SSAS Cube,事实上并不需要什么索引,因为所有的终端用户的查询都是在Cube上发生的,但是一个精心的索引设计将会提高那些在数据仓库上直接使用查询的应用,例如,关系型报表。

 

      4.    添加描述属性

除去代理键和业务键,其他所有列都是描述属性,用来分析信息。在数据模型上,我们总是尽量去包含最多的属性来为数据仓库增加有用信息。它们的数据类型可以是各种各样,比如,货币,百分率,不过大多数都是文字类型。

 

当我们新建一个数据仓库时,经常发现这些属性使用的数据类型的模式,比如使用一些列来保存一个50字以内的描述,然后另一些列使用一个长一些的100字的描述。一个有用的技术是使用SQlSevrer的User-defined  types特性的优点来为一些常见的列创建指定数据类型,比如ShortDesc,LongDesc。这将可以使建立属性的方法规范化,并且会使修改列变的简单。

 

    5.创建时间维度表

时间表含有我们要度量的一个时间的记录。比如,每天。这个表包含多个描述属性来支持多钟层次比如日历年和财政年。也支持一些属性来描述某天属于年中的第几天以及是否是公共假日。

虽然我们能够遵从一些通用的原则来使用自增长列来作为代理键,但是通常使用实际的DateTime列作为时间维度表的主键会更方便一些。因为实际的值即使是源系统也能识别。使用业务主键而不是代理键是基本一样的。这违反了总是使用代理键的设计原则,但是使一些操作,比如往事实表中装载数据,更加简单,因为避免了为每一天都查找代理键。

 

在我们建立好了所有的维度表之后,我们可以来设计事实表

 

建立事实表

事实表为每个关联到此事实的维度表建立一列来存放维度表的代理键。也为每个度量值建立一列。比如,事实表和客户维度有两个关系,那么我们需要加ShippingCustomerKey和BillingCustomerKey列来表示,我们也需要三个时间列(OrderDateKey,DueDatekey,and ShipDateKey)来为每一个出货事实表达不同的时间。

 

大多数事实表为单一Key Values的集合含有单条记录,所以事实表的逻辑主键通常是维度表的键,但是,大多数信息都是在某些级别的汇总上进行分析(尤其使用SSAS的BI解决方案),所以它通常不在乎是否你在复合主键上有多条记录,因为它们将会被聚合--除非在一些关系型报表的场景中。因为这个原因,主键约束通常都不被加到事实表中。并且任何潜在的避免重复事实记录的需求都是在ETL的过程中来处理。

 

在有关维度表的描述中,使用SSAS Cube的BI解决方案查询信息时数据仓库不需要什么索引,但是值得做的事是给事实表加上聚集索引,通常加在某一个时间key 列上。因为数据经常被以时间区间来查询,所以如果事实数据在物理上按照时间来组织,那将很有用。

 

键处理完之后,我们可以添加剩余的度量值,通常我们选择最小的数据类型,因为事实表通常都特别大,仔细选择的小的数据类型将会节省大量的空间,并带来性能上的提升,但是过小的数据类型,将会带来ETL过程的失败,并且需要增大列的大小后重试。

 

  • 处理参照完整性(RI)

参照完整性是一个处理表间关系的继续,并且有时在数据仓库中使用来保证每个事实表中键在维度表中有对应的行。如果Data-Loading 过程试图往事实表中加一行记录,记录中包含维度Key,但是这个Key并不存在维度表中,这个过程将会失败,这就是参照完整性,来保证不会有不匹配的记录。

 

对于参照完整性是否应该应用于数据仓库,一直存在针锋相对的观点。不过我们可以认为,参照完整性在数据仓库里不是必须的。主要原因是我们总是为维度使用代理键。因为这些键仅仅是在数据仓库中可用,在装载事实表时,一个Look Up步骤总是需要发生,用来将业务键翻译成代理键。如果Look Up 失败,这个记录要么添加失败,要么使用一个特别的代理键(指向Missing Or UnKown 维度记录)。

 

所以,和OLTP中RI是绝对需要的不同,数据仓库严格使用代理键的一个主要的特征是RI是在data loading过程中强制执行的。正是因为这个原因,数据仓库中声明外键约束不是必须的,优点是装载的性能得到提高,并且数据装载的顺序有时能变的更加灵活。一个潜在的缺点是,在数据装载过程中,任何错误都是难于捕获的,除非你试图校验数据仓库中的数量。所以有时在开发过程中加入外键引用也是很有用的。

 

只有你打破原则--总是使用代理键 --的时候才会有例外,因为你不需要LookUp的过程。例如时间维度,但是你需要添加一些处理来保证所有添加到事实表中的新记录的时间区间都是时间维度表中,并且如果不在时间维度表中则触发一些处理来添加时间。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值