当维度建模遇上3NF

作者:姜玲
2007/4/4 14:38:27
本文关键字: ttnn 2006年05期

近来一个热门话题是谈数据仓库架构中的分层,谈到几种不同的分法,整个帖子已经非常长了,还有继续的趋势,于是这里重启一个话题。

上次话题是innovate挑起的,他强调一个观点,需要CDW,这是介于EDW和DM之间的一层。原因既然EDW是3NF,而DM是维度建模的(这是一个前提,否则就不用谈CDW),那么从3NF到维度建模是如何过渡的呢?

这个理由能够说服我,因为从确实需要过渡。但后来想想,又产生一些疑惑,3NF和维度建模到底有多大差异呢?需要一个独立的环节来过渡一下?老实说,对于inmon和kimball的书籍,我并没有仔细研读,也是想通过在这里讨论和大家探讨。但我相信一些道理,在实际架构中,没有绝对的设计原则,所谓3NF,第三范式,只是指出一种理想的ER设计模式,但实际的设计大家也都知道,一般人们都会说,"为了性能、应用方便,会考虑适当的冗余。",可这适当冗余不也就破坏了3NF吗?而且这适当可说不准是多少。

因此,我想说,这EDW并不是绝对的3NF,而所谓维度建模又能够和3NF有多少冲突呢?在他的概念里面,星型模式是一种不太符合3NF的ER结构,但只是不"太",如果改成雪花模式,是不是也就是3NF了呢?

可能在我们的讨论中已经习惯将两者对立起来,是3NF就不是维度建模,是维度建模就不是3NF,EDW是3NF的,DM则是维度建模,他们是完全不搭嘎的ER设计。在软件架构中,有一种"阻抗不匹配"的情况,是说OO和ER模型两种思路不一样,因此有专门的软件层(持久层),甚至中间件来解决这个不匹配(如Hiberlate)。可3NF到维度建模是否有如此的"不匹配"实在值得怀疑。

innovate还提出从EDW到DM其他要做的事情,例如生成一致维度、一致事实,这应该跟是否符合范式也没有关系,只是说多个集市能够复用他们吧。因为这是kimball的总线架构理论,所以不能放到Inmon的EDW中,在EDW中不应该出现维度这个概念,是不是这个理由,才导致了CDW的出现呢?

譬如拿上次讨论中那个场景来说,参见http://groups.google.com/group/ttnn/msg/30923b6be074be30:

客户级别,三个地市的系统有三份不同的客户级别代码表,那么在EDW中如何设计呢?总不会还是三张表吧,必定是已经合成一张,并且在整个企业的信息模型中,如果要谈到客户级别,那肯定就在这张表中。这张表的表名可能叫做CODE_CUSTLVL,表示这是代码表。到集市中,显然这会作为一个客户级别维存在。那么就必须要将它改成DIM_CUSTLVL,并放在CDW中,才显得"一致"吗?这一个代码表,另一个维表,他们的结构有什么区别呢?可能都是[级别ID、级别描述、源系统、变更时间] 而已。

可能客户级别是一个比较简单的例子,这个维只有一个层次。那么我们拿日期维来说,这个层次够丰富,放在EDW中,确实不符合3NF,但即使放在EDW中又有多大危害?EDW最终不也是一个"适当"冗余的库吗?将所有一致维度都放到EDW中,是否就导致它变质,不是3NF了呢?如此,可以考虑将星型模式的维度变成雪花模式的,那总算是3NF了吧。

说了这么多,俺终于得出一个结论——CDW是没有必要的。

goldenfish 20060523

我觉得,EDW中关键是解决如何“保留历史”的问题。例如,对于一个客户信息表:

<客户ID ,客户姓名,客户住址,客户性别,婚姻状态、客户话费余额、客户欠费余额>
如何保留客户信息的历史?在业务系统中,可能不保留历史(例如客户更名,只保留最新的名字),而直接使用覆盖写的方法。但数据在仓库中要保留历史。

我们至少有三种方法:

1.建一个包含上述信息的客户信息表,当客户任何一项信息变动时,均插入一条记录(仓库中的客户信息表使用代理主键。)

2.将客户信息分类,分为“偶然变动”的信息和“频繁变动”的信息。将偶然变动的信息定义为整个数据生命周期只发生数次变动的;频繁变动则随时间周期变动。

偶然变动的:客户姓名、客户性别、婚姻状态

频繁变动的:客户话费余额,客户欠费余额

偶然变动的放入一个表中,频繁变动的分别用不同表记录(除非变动周期一致);

将客户信息分成了三个表:客户基本信息表和客户的话费余额变动信息表、客户欠费余额变动信息表。在基本信息表中,只要一项基本信息变动,则增加一条记录;在频繁变动表中,随每次变动就增加一条记录。

3.对于任何一项可能变动的属性,均使用单独的表(除非变动周期一致)。这样就出来性别历史表、住址历史表、婚姻状态历史表、话费余额历史表、欠费余额历史表等等。

可以看出,从1到3是逐步减少冗余,符合3NF的要求的,减少了数据的不一致,减少了存储空间。但在使用这些信息的时候,则不可避免会付出更多的时间代价。(方案1相当于是对方案3预先做了各个表的连接。)

说仓库是3NF的,则它应该是符合方案3的。但实施的时候可以变通权衡,使用方案2的思路。说来说去这和仓库的处理能力又相关了,能力强就当场算,不强就冗余存用空间换时间。

越是满足3NF,离星型模式就越远,中间要做的工作就越多。星型模式的事实表,必须连接每个属性的历史状态表才能取得某一时点的视图。这可能是CDW存在的原因?

innovate 20060523
至于保留历史问题,我觉得不是两派争论的焦点,属于小问题。因为Kimball早在他的理论就提出了缓慢变化维和快速变化维的设计和维护,就是为了保留历史信息。

比如我一个前同事问我,如果变化维的时间长了,会不会留下垃圾维度。我觉得这个问题没关系,因为数据仓库的信息保留可以分几个阶段,最近阶段(如1天/周或月),近期阶段(1月/年或者2、3年),以及历史阶段(1年,或者n年以前的数据),一般历史阶段就要放到磁带库备份了,那么我们的变化维也需要这样的处理,不然同期的事实表都处理了,维度表还保留着有何意义呢?

其实有没有必要,我们需要拿事实说话,如果哪位做过EDW数据仓库项目,且数据集市是维度建模,但是是直接过渡过去,没有使用中间层,那是否有成功案例?至少我在国内没有听说过,我见过一个国内的EDW项目数据集市没有采用维度建模方式,客户的感觉我不是很了解,但是我看得出扩展性很差。由于没有专门的维度描述,每生成一个汇总表,都会把像零次用户、使用长途用户等需要ETL出来的维的名称和对应的指标写在程序里,这样的扩展性是可想而知的,而且很难维护,因为可能多个主题需要用到这些维,你一个一个去算?

如果说EDW是否使用了大量的维度建模思想,比如建立专门的维表去描述一个维、专门的事实表去描述某个主题。不是这样的,那会产生大量冗余。比如一个主题的维、指标多达上百甚至几百,按照EDW的设计思想不应该用一个表去描述,而是不同的表关联共同组成一个主题,这样冗余很小,而采用较好的数据仓库产品也能保证较高的效率(如Teradata)。

所以如果在EDW思想里采用维度建模需要谨慎,弄不好就不伦不类,即有大量冗余而影响多表查询的效率,又没有采用Kimball的思想使维表和事实表保持一致,这样的项目可能会背离高效、高数据质量、高扩展性的终极目标。


责编:姜玲
vsharing 微信扫一扫实时了解行业动态
portalart 微信扫一扫分享本文给好友
著作权声明:kaiyun体育官方人口 文章著作权分属kaiyun体育官方人口 、网友和合作伙伴,部分非原创文章作者信息可能有所缺失,如需补充或修改请与我们联系,工作人员会在1个工作日内配合处理。
畅享
首页
返回
顶部
×
畅享IT
    信息化规划
    IT总包
    供应商选型
    IT监理
    开发维护外包
    评估维权
客服电话
400-698-9918
Baidu
map