3.5 确定分析内容的构成:事实及其粒度
事实表是数据库中最大的表,是星形模型结构的核心。事实表包含了基本商业事务的详细信息,是对商务活动进行客户关系、销售趋势和产品趋势等分析的素材。事实表的设计包括对事实的选择、量度的构造、粒度的设计和聚合的设计等。
3.5.1 事实、度量和事实表
事实是各个维度的交点,是对某个特定事件的度量。维度中的属性描述的是维本身的属性,比如客户的性别、年龄、姓名和地址,这些都是客户的固有属性。
度量是客户发生事件或动作的事实记录,比如客户打电话,可能选择的度量有通话时长、通话次数和通话费用等;客户购买商品,可能选择的度量有购买的次数、购买商品的金额和购买商品的数量等。度量变量的取值可以是离散的数值,也可以是连续的数值。比如,客户通话次数是离散的数值,而客户购买商品的金额是连续的数值。度量变量也可以在某个元素集合内取值。比如客户对公司服务质量的评定可以是很好(Excellent)、好(Good)、一般(Fair)和差(Poor)中的一个。
事实表则是位于星形架构或雪花形架构中间,用来记录商务事实和相应统计指标的表。同维表相比,事实表具有如下的特征。
● 记录数量很多。
● 事实表中除了度量变量外,其他字段都是同维表或者中间表(对于雪花形模型)的关键字。
● 如果事实相关的维度很多,则事实表的字段数也会比较多。
从事实表记录数多的特征中,我们可以得到事实表设计的一个感性认识,即事实表应当尽量减小一条记录的长度,只有这样才能避免事实表过大而难于管理。相对维表来说,事实表是“细长”的结构,如图3-35所示。
图3-35 事实表的特征
3.5.2 事实表的设计
由以上分析可知,事实表中一般要包含2部分:一是由主键和外键所组成的键部分,另一部分是用户希望在数据仓库中所了解的数值指标,这些指标是为每个派生出来的键而定义和计算的,称为事实或指标。由于事实是一种度量,所以事实表中的这种指标往往需要具有数值化和可加性的特征。但是在事实表中,只有那些具有完全可加性的事实才能根据所有的维度进行累加而具有意义。而事实表有一些事实表示的是某种强度,这类事实就不具有完全加法性,而是一种半加法性。例如,账目余款反映的是某个时间点的数据,它可以按照地点和商品等大多数维度进行累加,但是对于时间维度则例外,将一年中每个月的账目余款进行累加是毫无意义的,而决策者则可能需要了解所有地区和所有商品账目余款的累加值。在事实表中还有一些事实是非加法性的,即这些事实具有对事实的描述特性,在这种情况下一般要将这些非加法性事实转移到维度表中。
以事实表中度量的可加性情况,可以把事实表及其包含的事实分为4种样式。
1.事务事实
事务事实以企业事件的单一情况为基础,因此通常只包含事实的次数这一种度量条件,应该尽可能以最低级别来表示。比如银行的ATM提款机的提款次数,使用某种服务的次数等。
2.快照事实
快照事实以企业在某一特定时间的特殊状态为基础。也就是只有在某一段时间内才出现的结果。它们也许没有包含所有维的条件,比如不是所有的产品每天都有销售量。
3.线性项目事实
这类事实通常用来储存关于企业经营项目的详细信息。包括表现与企业相关的个别线性项目的所有度量条件,比如销售数量、销售金额、成本和运费等数值数据,也就是关键性能指标。此类事实运用范围很广,比如采购、销售和库存等。
4.事件(状态事实)
这是类特殊的事实,通常只表示事件发生与否和一些非事实本身具备的细节。它所表现的是一个事件发生后的结果变化,并且没有度量数值表示。如哪些产品在促销期间内没有卖出,有还是没有,就是事件或状态事实所表现的结果。
在事实表模型的设计中还需要注意到派生事实。派生事实主要有2种,一种是可以用同一事实表中的其他事实计算得到,例如销售行为中的商品单价可以用商品的销售总金额和销售数量计算得到,对于这些派生事实一般不保留在事实表中;另一种是非加法性事实,例如各种商品的利润率等各种比率。
在事实表模型的设计中必须要考虑到事实表中的这些事实特性,通过多次反复来确定。首先,通过调查确定所有可能的基本事实和派生事实;然后,对所有的事实按照功能或某种方式进行排序,以删除重复的事实;接着,确认那些基于不同准则但是有相同性质的派生事实,例如公司门市销售总额与地区销售总额虽由于维度的不同而被定义为不同的事实,但实际计算方法是一样的;最后,再一次确定事实表模型,在确认中要检查所有的计算派生事实的基本事实是否已经包含在模型中,并且与用户取得—致。
在设计事实表时,一定要注意使事实表尽可能地小,因为过于庞大的事实表在表的处理、备份和恢复及用户的查询等方面需要较长的时间。在实际设计时,可以利用减少列的数量、降低每一列的大小和把历史数据归档到单独的事实表中等多种方法来降低事实表的大小。另外,在事实表中还要解决好数据的精度和粒度的问题,下面将阐释粒度的设计方法。
3.5.3 粒度的设计
在数据仓库中的数据分为4个级别:早期细节级、当前细节级、轻度综合级和高度综合级。如图3-36所示,源数据经过综合后,首先进入当前细节级,并根据具体需要进行进一步综合,从而进入轻度综合级乃至高度综合级,老化的数据将进入早期细节级。从中可以看出,数据仓库中存在着不同的综合级别,这就是 “粒度”的直观表现。
图3-36 数据仓库中的数据细节级别
粒度模型是数据仓库设计中需要解决的十分重要的问题之一。所谓粒度是指数据仓库中数据单元的详细程度和级别。数据越详细,粒度就越小,级别也就越低;数据综合度越高,粒度就越大,级别也就越高。
1.粒度对数据分析的影响
1)影响逻辑结构的设计
先举一个粒度设计的例子,Adventure Works Cycles公司的管理者想按照国家、区域、分区域和分区域内的销售员这样的层次关系来查看公司的销售情况,按照此需求可以得到如图3-37所示的设计结果。它是通过将地理层次国家、区域和分区域嵌入到销售员维度得到的。
图3-37 细化到销售员层次的设计结果
如果公司的决策者认为不需要了解具体到某个销售人员的情况,而只需要了解各个地理区域的销售情况,则没有必要把销售员维作为一个维度,把地域相关的表综合成为地理维度就可以了,设计结构如图3-38所示。
由以上实例可知,对事实粒度需求的不同,会直接导致数据仓库逻辑设计的差异。
图3-38 细化到分区域层次的设计结果
2)影响数据的存储
粒度对数据仓库最直接的影响就是存储容量。如图3-39所示的例子,按照每“月”统计的客户购买数据和按照每次消费记载的客户购买数据,两者的数据量相差极大。不妨假定每个字段为8个字节,每个客户一天有5次消费,则1个客户1个月的消费细节数据的数据量为8×6×30×5=7200字节,而1个客户1个月的消费汇总数据的数据量为8×4=32字节。
图3-39 不同粒度的储存容量示例
3)影响分析效果
不同的粒度设计对应不同的分析需求,若分析需求和粒度设计不匹配,则会直接影响分析效果。
因为数据的综合使得细节信息丢失,所以若分析需求的粒度小于设计的粒度,则需求不可能得到满足;反之,若分析需求的粒度大于设计的粒度,则查询会在更小的粒度上进行统计运算后才能回答,这将增加用户的等待时间。
例如在图3-40中,要回答“张某在2007年1月29号是否在北京买了一辆山地车”这样非常细致的问题,细节数据非常合适,而综合数据不可能回答。如果要回答“王某在2006年1月到2006年12月自行车配件的总消费是多少”这样综合程度较高的问题时,使用综合数据则可以迅速地回答这个问题。如图3-40综合数据和细节数据的用途和查询代价所示,很好地说明了这一点。
图3-40 综合数据和细节数据的用途和查询代价
由于数据仓库的主要作用是决策分析,因而大多数查询都基于一定程度的综合数据之上,而只有少数查询涉及到细节。因此在数据仓库中,设计多重粒度是必不可少的。下面具体讲解粒度的设计问题。
2.粒度的设计技巧
由以上的分析可知,数据仓库的性能和存储空间是一对矛盾。如果粒度设计得很小,则事实表将不得不记录所有的细节,储存数据所需要的空间将会急剧的膨胀;若设计的粒度很大,虽然由于事实表体积大而带来的诸多问题能够得到一定程度的缓解,但决策者不能观察细节数据。粒度的设计成了事实表设计中的重要一环。
1)设计步骤
(1)粗略估算
确定合适的粒度级的起点,可以粗略估算数据仓库中将来的数据行数和所需的直接存取存储空间,粗略估算可以按照以下步骤完成。
① 确定数据仓库中将要创建的所有表,然后估计每张表中行的大小(确切大小可能难以知道,估计一个下界和一个上界就可以了)。
② 估计一年内表中的最少行数和最多行数。这是设计者所要解决的最大问题。比方说一个顾客表,就应该估计在一定的商业环境和该公司的商业计划影响下的当前的顾客数;如果当前没有业务,就估计为总的市场业务量乘以市场份额;如果市场份额不可知的话,就用竞争对手的业务量来估计。总之,要从一方或多方收集顾客的合理估算信息开始。如果数据仓库是用来存放业务活动的话,就要估计顾客数量,以及估计每个时间单位内业务活动量。同样,可用相同的方法分析当前的业务量、竞争对手的业务量和经济学家的预测报告,等等。
一旦估计完一年内数据仓库中数据单位的数量(用上下限推测的方法),就用同样的方法对5年内的数据进行估计。粗略数据估计完后,就要计算一下索引数据所占的空间。对每张表(对表中的每个键码)确定键码的长度和原始表中每条数据是否存在键码。
③ 将各表中行数可能的最大值和最小值分别乘以数据的最大长度和最小长度。另外,还要将索引项的数目与键码的长度的乘积累加到总的数据量中去。
(2)确定双重或单一的粒度
一旦估计完成后,下一步就要将数据仓库环境中总的行数和表3-8中所示的表格进行比较。根据数据仓库环境中将具有的总的行数的大小,设计和开发必须采取不同的方法。以1年期为例,如果总的行数小于10 000行,那么任何的设计和实现实际上都是可以的。如果1年期总行数是100 000行或更少,那么设计时就需小心谨慎。如果在头一年内总行数超过1 000 000行,那么就要请求采取双重粒度级。如果在数据仓库环境中总行数超过10 000 000行的话,必须强制采取双重粒度级,并且在设计和实现中应该小心谨慎。对于5年期数据,行的总数大致依据数量级改变,参见表3-8。
表3-8 存储空间与粒度设计层次的考虑
(3)确定粒度的级别
在数据仓库中确定粒度的级别时,需要考虑这样一些因素:要接受的分析类型、可接受的数据最低粒度和能存储的数据量。
计划在数据仓库中进行的分析类型将直接影响到数据仓库的粒度划分。将粒度的层次定义得越高,就越不能在该仓库中进行更细致的分析。例如,将粒度的层次定义为月份时,就不可能利用数据仓库进行按日汇总的信息分析。
数据仓库通常在同一模式中使用多重粒度。数据仓库中,可以有今年创建的数据粒度和以前创建的数据粒度。这是以数据仓库中所需的最低粒度级别为基础设置的。例如,可以用低粒度数据保存近期的财务数据和汇总数据,对时间较远的财务数据只保留粒度较大的汇总数据。这样既可以对财务近况进行细节分析,又可以利用汇总数据对财务趋势进行分析,这里的数据粒度划分策略就需要采用多重数据粒度。
定义数据仓库粒度的另外一个要素是数据仓库可以使用多种存储介质的空间量。如果存储资源有一定的限制,就只能采用较高粒度的数据粒度划分策略。这种粒度划分策略必须依据用户对数据需求的了解和信息占用数据仓库空间的大小来确定。
选择一个合适的粒度是数据仓库设计过程中所要解决的一个复杂的问题,因为粒度的确定实质上是业务决策分析、硬件、软件和数据仓库使用方法的一个折中。在确定数据仓库的粒度时,可以采用多种方法来达到既能满足用户决策分析的需要,又能减少数据仓库的数据量。如果主题分析的时间范围较小,可以保持较少时间的细节数据。例如,在分析销售趋势的主题中,分析人员只利用一年的数据进行比较,那么保存销售主题的数据只需要15个月的就足够解决问题了,不必保存大量的数据和时间过长的数据。
还有一种可以大幅降低数据仓库容量的方法.就是只采用概括数据。这样处理后,确实可以降低数据仓库的存储空间,但是有可能达不到用户管理决策分析中对数据粒度的要求。因此,数据粒度的划分策略一定要保证数据的粒度确实能够满足用户的决策分析需要,这是数据粒度划分策略中最重要的—个准则。
2)设计实例
下面以类似Adventure Works Cycles公司的生产部门数据仓库设计为例,如图3-41所示。由于对不同的生产业务查询需求的差异,这里采用多重粒度来设计。左边是操作型数据,记录的是完成若干给定部件的生产线运转情况,每一天都会积累许多记录,是生产业务的详细数据,最近30天的活动数据都存储在操作型的联机环境中。
操作型数据的右边是轻度汇总级的数据,轻度汇总级包括两个表,一个汇总某一部件在3个月中的生产情况,另一个汇总部件的组装情况,汇总周期为1年。真实档案级的数据包括每个生产活动的详细记录。
图3-41 生产环境的多重粒度
3)设计原则
粒度在数据仓库生命周期中是重要的考虑因素。它由业务问题所驱动,受技术的制约。如果粒度太大,就会丢失个别细节,就要花更多的处理时间来解开聚合;而若粒度太小,就会由于一叶障目而不见森林,许多宝贵的处理时间都浪费在建立聚合上。因此粒度设计主要是权衡粒度级别,对于业务量大,分析要求比较高的情况下,最佳解决办法则是采用多重粒度的形式。
而针对具体的某个事实的粒度而言,应当采用“最小粒度原则”,即将量度的粒度设置到最小。
假设目前的数据最小记录到秒,即数据库中记录了每秒的交易额。那么,如果可以确认,在将来的分析需求中,时间只需要精确到天就可以的话,就可以在ETL处理过程中,按天来汇总数据,此时,数据仓库中量度的粒度就是“天”;反过来,如果不能确认将来的分析需求在时间上是否需要精确到秒,那么,就需要遵循“最小粒度原则”,精确到“秒”以满足查询的可能需求。
3.5.4 聚合的设计
在事实表中存放的度量变量,根据其实际意义可分成可加性度量变量和非可加性度量变。可加性度量变量是指将变量相加后得到的结果仍然具有实际意义,可以把此结果计算后放在事实表中,以便在以后的查询中直接使用,这个相加的结果就是聚合。比如每个月的销售金额,通过将3个月的销售金额相加,就可以得到1个季度的销售金额;通过将12个月的销售金额相加,可以得到全年的销售总金额。
确定了数据仓库的粒度模型以后,为提高数据仓库的使用性能,还需要根据用户的要求设计聚合。数据仓库中各种各样的聚合数据主要是为了使用户获得更好的查询性能,因此聚合模型的好坏将在很大程度上影响到数据仓库的最终使用效果。
在设计聚合模型时,首先需要考虑用户的使用要求,其次要考虑数据仓库的粒度模型和数据的统计分布情况。
数据仓库的一般用户在其日常工作中己经有了按照地理位置、产品类型和时间范围的报告。在数据仓库的聚合设计中,应该对每个维进行审查,以确定哪些属性经常用于分组,这些属性的组合有多少。例如,如果考虑某一主题有4个维度,每个维度有3个可以作为聚合的属性,那么最多可以创建256个不同的聚合。当然.在实际工作中是没有必要创建这么多聚合的,只需考虑在数据仓库中经常使用的聚合。此时,可以审查数据仓库的需求分析文档,了解用户的需求情况。然后确定哪些内容会对聚合有影响,并通过对数据的审核获取每个维度中不同聚合的统计数据。
数据仓库的聚合模型的设计与数据仓库的粒度模型紧密相关,如果数据仓库的粒度模型只考虑了细节数据,那么就可能需要多设计一些聚合,如果粒度模型为多层数据则在聚合模型设计中可以少考虑一些聚合。
在建立聚合模型时还需要考虑作为聚合属性的数量因素。例如,在数据仓库中有1 000 000个值用于描述商品信息的最底层信息,如果用户在使用数据仓库时用500 000个值描述商品最底层的上一层次的信息,此时进行聚合处理并不能明显提高数据仓库的使用性能。但是如果商品上一层次的信息用75 000个值描述,那么就应该使用聚合表提高数据仓库的使用性能。
3.5.5 数据分割
如果粒度和分割都做得很好的话,则数据仓库设计和实现的几乎所有其他问题都容易解决。但是,假如粒度处理不当并且分割也没有认真地设计与实现,这将使其他方面的设计难以真正实现。数据分割是指把数据分散到各自的物理单元中去,使它们能独立地处理。分割是数据仓库中继粒度问题之后的第2个主要的设计问题。
为什么分割如此重要呢?因为小的物理单元能为操作者和设计者在管理数据时提供比对大的物理单元更大的灵活性。数据仓库的本质之一就是灵活地访问数据。如果是大块的数据,就达不到这一要求。因而,对所有当前细节的数据仓库数据都要进行分割。分割的原理类似如图3-42所示,由于全部销售记录过于庞大,可以按照不同的年度把它分为5个小的物理单元。
图3-42 数据分割处理
例如,在第2章用到的foodmart 2000.mdb中,由于设计该数据库的时候考虑到了它将要作为数据仓库使用,因此,对于销售事实按照年份分割成了sales_fact_1997、sales_fact_1998和sales_fact_dec_1998 3个表,对库存事实则分割成了inventory_fact_1997和inventory_fact_1998两个表,如图3-43所示。
图3-43 Foodmart数据库中的数据分割
在工程实践中,除了时间以外,还可以有多种数据分割的标准。例如商务业务、地理位置和组织单位或者各种标准的综合。