(sap实施)关于 SAP系统
的调整
12:47 代理键的考虑
代理键(surrogatekey)这个概念是球派提出来的,在这个链接中可以找到
kimball对它的描述,这篇文章还是 1998年写的,比较早了。我们在 2000年设
计 QiDSS时,采用的是 informix公司的方案,基于 redbrick、metacube,可以
说这个方案充满着球派的痕迹,毕竟 kimball就是 redbrick的创始人。在这种
情况下,我们不接收他的洗脑都难。使用代理键便是其中之一,kimball说了很
多好处,我们也没法去验证,更来不及去怀疑,反正一直都用着。不过时间长了,
就有人提出疑问,happypu在 dwway论坛上提出了这个问题,何谓代理建,atiger
给出了答案,比较常规的回答,代理键一个主要的功能是反映变化。可以换一个
角度来理解,从面向对象思想出发,一个维其实是一个 class,而维成员是他的
实例,object,在业务数据库的代码表中,主要记录的是当前状态,所以业务代
码表记录的的是最近时刻所有维成员对象,对象 ID就是码表主键。而对于数据
仓库中的维表,他要表示历史信息,要记录的内容是历史上所有的维成员对象,
而原有的业务主键肯定不能作为对象 ID,因为他不是唯一的了,而用业务主键联
合变更时间作为主键大家都不会同意吧。因此,代理键就出现了,它就是“历史
上所有的维成员对象”的对象 ID。当然,kimball还又很多其他的理由使用代理
键,这里也不鼓吹了,毕竟有些好处我也没有对比过。但是就使用代理键,在目
前项目中遇到的一些问题却是不得不说一下。
首先,代理键的维护问题。代理键是一种自动增加的整型字段,如 oracle的
sequence,sqlserver的 identy字段,对于那种慢速变化维(SCD,这同样是球
派提出的,请看 kimball对 slowlychangingdimensions的描述。),要保证在数
据仓库建设生命周期内,业务代码和代理键的对应关系是稳定的。例如有个项目,
在实施过程中,一旦维表结构有稍许修改,就删掉所有维表数据重新初始化,而
此时很可能打乱原有的对应关系。原来的 A对应 2,重新初始化以后就对应到 3
上去了。造成的后果可以想象,原来相关的事实表数据需要重新装载,甚至如果
有引用了这个值的报表 SQL,存储过程都需要修改。所以在代理键的维护过程中,
一定要保证对应关系的稳定性和每次维护前的备份。
再者,代理键被客户接收的程度。在 onteldatastage讨论组中曾经讨论过着个
问题。目前阶段,报表还是关键的应用,在报表 SQL中引用代理键总不如引用业
务键值那样顺,例如客户对于业务类型代码、城市代码都很熟悉,一般看到代码
就知道是那个业务或城市,而使用代理键值,让客户很迷糊。所以这不利于系统
的推广。对此,暂时没有想到什么好的办法,只能暂时先在维表中放上业务代码
字段。但是仍有个问题,代理键和业务代码不一定是一对一关系的,例如多个数
据源系统的不同代码映射到同一个代理键。这种情况,嘿嘿,只能看从哪个数据
源出报表需求多了。
08:59再探数据形态
我们以前项目中经常想对度量进行分类,因为有些度量在计算汇总时要区别对待。
为了区分,我们分成时点值和时期值,对于时点值,是不可累加的,例如在网用
户数、历史欠费总金额、帐户余额等。这些度量反应的时特定时间点的一个状态
值,不能在时间上累加,所以我们描述这个指标的时候,一般也都需要带上一个
时间点定语,例如截至 4月 1日的在网用户数、到 9月 30日的历史欠费金额等。
而对时期值,反应的是某个时间周期类的发生的值,例如通话费用、通话时长、
新增用户数等度量,都可以在时间上累加。表述这些度量一般带上一个时间区间
的定语,例如 8月份的通话费用、9月新增用户数等等。一般 OLAP工具对这两种
度量都是支持的,例如 Cognos在度量选项中可以指定是求和还是求期末值或是
期初值,能够求和的就是时期值,对于求期末、期初的度量,一般是时点值(要
应用此特性,必须明确指明一个时间维,可见这两种值和时间是紧密联系的)。
昨天写的数据仓库中的数据形态中,提到 ODS有两种形态数据,一种是事件型,
一种为快照型。快照型数据记录当前时间点的状态值,事件型数据记录特定事件
发生。这两种不同形态对于抽取增量有很大帮助。但是其他的分类方法,这是
kimball在他的文章中提出来的,请看 FundamentalGrain。此文中提出三种事实
表的数据形态分类,我觉得比我的分类更合理一些。因为事件型和快照型这两种
分类主要是从增量抽取角度考虑的,例如原来考虑月帐单这种表应该属于哪一类
时,有点模糊,便将至归结于事件型数据中,认为每个用户开帐是一种事件,未
免有些牵强。
因此,重新考虑数据形态在时间上的分类,可以分成三种。事件型
(TransactionGrain)、周期快照型 (PiriodicSnapshotGrain)和累积快照型
(AccumulatingSnapshotGrain)。其中,事件型和我提到的事件型是差不多的意
思,它记录的每一次事件的发生,包括发生的环境(维度)和发生的值(度量),
例如通话详单表,日志表等。而我的快照型表还需要细分成周期快照和累积快照,
而原来我将周期快照归于事件型。因为周期快照反应的是一段时间周期内发生值,
例如月底出帐,月帐单记录每个用户的消费金额,就是上月通话费用的汇总。因
为这种数据带有明显的周期性,例如每月,如果将它和事件型数据混为一谈有些
说不过去。但是从应用周期快照型数据来说,他的特点和事件型数据有非常相似,
例如都记录的是发生值,再如它们提交后一般都不会再做 update操作。而累积
快照型和我的快照型相对应,它记录是一个时间点上实体的状态,这种数据从实
体的生命周期一开始一直更新到生命结束,例如用户表中,从用户创建开始,用
户开机、停机、状态改变都会直接更新这些数据,最后,用户销户了,更新他的
有效标志,从此这条记录基本不会再修改了。
再结合一开始提到的时点值、时期值,前者记录某一时刻状态,一般都在累积快
照型表中,当然也有可能在周期快照型表中,表示是期末那一刻的状态值,例如
充值余额可以记录在用户表中同时也可能会在月帐单表中出现。而时点值一般在
事件型数据中是不会出现的。时期值一般存在于事件型核周期快照型表中,因为
他表示发生值,在累积快照型中没有这种值。当然,有时候你可以从另一个角度
将累积快照型看作是一种事件型表,因为前者记录实体的生命周期变化,因此这
些变化,你甚至可以看作是一种事件。从而,再以用户表为例,你可以统计新增
用户多少,离网用户多少等时期值。