《分析服务从入门到精通读书笔记》第一章、其他可选表结构(6)
在业务数据库中,保证数据在所有应用程序中一致是极为重要的:如果在系统的某一部分修改了顾客的地址,这个修改后的地址立即在系统的所有部分显现出来,由于这种一致性的需要。倾向于将业务数据系统拆分成许多个表,这样任何值只在单个表中存储一次。任何时候需要某个值,包含这个值的表的连接就会被创建。保证一个值只存储在一个地方是规范化(normalization)进程的一个部分,这在业务系统数据库系统是十分重要的。
在数据仓库维度中,可能有许多属性来构成自然层次结构。熟悉创建业务系统数据库的数据库设计师希望将维度规范化。从而使层次结构中的妹级都有一张独立的表。例如,业务数据库的设计者可以通过创建一个子类表和一个类别表来规范产品维度。其中子类表中的每一个子类只出现一次,类别表中的每一种类型也只出现一次。这当然需要产品和子类表中的外键分别关联到产品和类别表中的主键。
然而,如果使用数据仓库中的数据来创建报表,许多的连接是查询变慢。例如,假设我们想查看2011年自行车的销售额度。为了按自行车进行聚合,需要将事实表中的每一行和产品表、子类表和类别表进行连接。为了以2011年进行聚合,需要将事实表和月度表、季度表,最后和年度表进行连接,然后将这些行中的销售总额累加。相比于将所有的产品属性和所有的日期属性各自单独存储在单张表中,将全部的产品维度和日期维度与事实表连接是报表查询更慢。
因此,在许多数据仓促中,单个维度的全部属性存储在单个维度表中,即这意味着类似于类别和年份这样的属性成员被冗余的存储了多次单张表中存储荣誉值的行为被称作对数据的反规范化(其实也就是范式)。执行单个连接去查找年份,执行连一个连接去查找类别。比用许多连接获得相同的数据要快的多,因此,在数据仓储中对维度表反规范化通常是值得的。
对每个维度创建一个单独的反规范化的表,这将产生一种星型模型(star schema)。当把星型模型会出来可以看出模型绘制出来后可以看到,每个事实表被每个维度表所包围。看起来想星星。对于每个维度进行规范化,每个维度会有若干个表。这就产生了一种雪花型模型(snowflake schema),因为星型的“点”分裂形成小的分支,看起来像雪花,实际上,并不是数据仓库是星星或雪花性模型,因为在同一个数据仓库中,有的维度就可能被完全规范化为雪花模型,而有的维度可能完全反规范化为星型模型。
如果是为了达到从关系型数据库中中创建报表的目的而创建出具仓库,那么需要仔细考虑每个维度是应该如何存储在单个星型模型维度还是存储在多个雪花型维度表中。然而,如果数据仓库主要用作分析服务的数据源,星型模型和雪花型模型之间的差异就不是那么明显了,这时可以基于其他的理由来做出设计决定,比如那种数据库更容易创建和更新。
具有不对称层次结构的维度,例如雇员维度,需要在雪花型模型维度的设计中有小的变动。在雇员维度中,键属性成员都是雇员。同时每个雇员的管理者也是雇员。在标准的雪花性维度中,父成员在新的级中,并创建新的表。但与标准的雪花型不同的是,在雇员维度中,父成员只指回了原维度表中的一个不同的维度的键属性成员。这被称作父子维度表(parent-child dimension)。因为父成员和子成员在同一个表里。用关系型数据库的术语来说,这种在一个表中从一个属性指回到该表主键的过程称作自引用连接( self-referential join)。父子维度为层次结构组织提供了很大的灵活性,但查询一个自引用连接的表会变得很困难。
总结
通过本节,我们学习了如何在关系型数据仓库中实现维度的数据模型,数据仓库又包含了度量值(也叫事实)的事实表,以及包含属性的维度表。数据仓库的设计者可以选择使用一组雪花性模型的维度表来存储自然层次结构,而在星型模型的表中存储维度的所有属性,具有不对称层次结构的维度可以存储在具有自引用连接的表中。
我们无法使用关系型数据库的数据仓库去实现维度数据模型的全部方面,因为能存储在关系型数据库中的元数据是有限的。在维度表中,属性名(列名)是元数据。但属性成员名则是表中行的数据。星型模型的维度表维度表没有关于属性应如何组织层次结构的元数据。例如,如果产品维度是存储在单个星型模型的维度表中,则表中就没有说明产品聚合成能聚合为类的子类信息。当然,我们可以将自然层次结构组织成一组雪花型模型的表。但没有一种能够指定非自然层次结构中级的方法。没有关于属性成员应该如何排序的元数据,也没有指定非自然层次结构中级的方法。没有关于属性成员应该如何排序的元数据,也没有指定那些属性是可聚合的,那些是不可聚合的。每个事实表包含了单级别的细节数据,因此没有汇总或聚合值,也没有元数据说明能运用到事实的合适的聚合方式。最后,在数据仓库中,维度和事实数据存储在独立的表中。当查询数据仓库时,必须在查询指令中包含如何将维度和事实表进行连接。