大数据之路读书笔记-11事实表设计

文章目录

  • 大数据之路读书笔记-11事实表设计
    • 11.1 事实表基础
      • 11.1.1 事实表特性
      • 11.1.2 事实表设计原则
      • 11.1.3 事实表设计方法
    • 11.2 事务事实表
      • 11.2.1 设计过程
      • 11.2.2 单事务事实表
      • 11.2.3 多事务事实表
      • 11.2.4 两种事实表对比
      • 11.2.5 父子事实的处理方式
      • 11.2.6 事实的设计准则
    • 11.3 周期快照事实表
      • 11.3.1 特性
      • 11.3.2 实例
      • 11.3.3 注意事项
    • 11.4 累积快照事实表
      • 11.4.1 设计过程
      • 11.4.2 特点
      • 11.4.3 特殊处理
      • 11.4.4 物理实现
    • 11.5 三种事实表的比较
    • 11.6 无事实的事实表
    • 11.7 聚集型事实表
      • 11.7.1 聚集的基本原则
      • 11.7.2 聚集的基本步骤
      • 11.7.3 阿里公共汇总层
      • 11.7.4 聚集补充说明

11.1 事实表基础

11.1.1 事实表特性

事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度和与业务过程有关的度量。
事实表中一条记录所表达的业务细节程度被称为粒度。通常粒度可以通过两种方式来表述:一种是维度属性组合所表示的细节程度:一种是所表示的具体业务含义。
作为度量业务过程的事实,一般为整型或浮点型的十进制数值,有可加性、半可加性和不可加性三种类型。可加性事实是指可以按照与事实表关联的任意维度进行汇总。半可加性事实只能按照特定维度汇总,不能对所有维度汇总,比如库存可以按照地点和商品进行汇总,而按时间维度把一年中每个月的库存累加起来则毫无意义。还有一种度量完全不具备可加性,比如比率型事实。对于不可加性事实可分解为可加的组件来实现聚集。
相对维表来说,通常事实表要细长得多,行的增加速度也比维表快很多。
维度属性也可以存储到事实表中,这种存储到事实表中的维度列被称为“退化维度”。与其他存储在维表中的维度一样 ,退化维度也可以用来进行事实表的过滤查询、实现聚合操作等。
事实表有三种类型:事务事实表、周期快照事实表和累积快照事实表,具体内容后面章节会详细介绍。事务事实表用来描述业务过程,跟踪空间或时间上某点的度量事件,保存的是最原子的数据,也称为“原子事实表”。周期快照事实表以具有规律性的、可预见的时间间隔记录事实 ,时间间隔如每天、每月、每年等。累积快照事实表用来表述过程开始和结束之间的关键步骤事件 ,覆盖过程的整个生命周期,通常具有多个日期字段来记录关键时间点, 当过程随着生命周期不断变化时,记录也会随着过程的变化而被修改。

11.1.2 事实表设计原则

原则1:尽可能包含所有与业务过程相关的事实
事实表设计的目的是为了度量业务过程,所以分析哪些事实与业务过程有关是设计中非常重要的关注点。在事实表中应该尽量包含所有与业务过程相关的事实,即使存在冗余,但是因为事实通常为数字型,带来的存储开销也不会很大。
原则2:只选择与业务过程相关的事实
在选择事实时,应该注意只选择与业务过程有关的事实。比如在订单的下单这个业务过程的事实表设计中 ,不应该存在支付金额这个表示支付业务过程的事实。
原则3:分解不可加性事实为可加的组件
对于不具备可加性条件的事实,需要分解为可加的组件。比如订单的优惠率,应该分解为订单原价金额与订单优惠金额两个事实存储在事实表中。
原则4:在选择维度和事实之前必须先声明粒度
粒度的声明是事实表设计中不可忽视的重要一步,粒度用于确定事实表中一行所表示业务的细节层次,决定了维度模型的扩展性,在选择维度和事实之前必须先声明粒度,且每个维度和事实必须与所定义的粒度保持一致。在设计事实表的过程中,粒度定义得越细越好,建议从最低级别的原子粒度开始,因为原子粒度提供了最大限度的灵活性,可以支持无法预期的各种细节层次的用户需求。在事实表中,通常通过业务描述来表述粒度,但对于聚集性事实表的粒度描述,可采用维度或维度属性组合的方式。
原则5:在同一个事实表中不能有多种不同粒度的事实
事实表中的所有事实需要与表定义的粒度保持一致,在同一个事实表中不能有多种不同粒度的事实。
如表 11.1 所示为机票支付成功事务事实表,粒度为票一级的,而在实际业务中,一个订单可以同时支付多张票,如 ID 100901 的订单包含三张机票, ID 100902 的订单包含两张机票, ID 100903 的订单包含一张机票。在该事实表的设计中,票支付金额和票折扣金额两个事实与表定义的粒度一致,并且支持按表的任意维度汇总,可以添加进该事实表中。而订单支付金额和订单票数作为上一层粒度的订单级事实,与该票级事实表的粒度不一致,且不能进行汇总。比如订单 ID100901 的订单支付金额为 3700 元,订单票数为3张,如果这两个度量在该表进行汇总计算总订单金额和总票数,则会造成重复计算的问题所以不能作为该表的度量选入。
原则6:事实的单位要保持一致
对于同一个事实表中事实的单位,应该保持一致。比如原订单金额、订单优惠金额、订单运费金额这三个事实,应该采用一致的计量单位,统一为元或分,以方便使用。
原则7:对事实的 null 值要处理
对于事实表中事实度量为null 值的处理,因为在数据库中 null值对常用数字型字段的 SQL 过滤条件都不生效,比如大于、小于、等于、大于或等于、小于或等于,建议用零值填充。
原则8:使用退化维度提高事实表的易用性
Kimbal 维度建模中,通常按照星形模型的方式来设计,对于维度的获取采用的是通过事实表的外键关联专门的维表的方式,谨慎使用退化维度。而在大数据领域的事实表设计中,则大量采用退化维度的方式,在事实表中存储各种类型的常用维度信息。这样设计的目的主要是为了减少下游用户使用时关联多个表的操作,直接通过退化维度实现对事实表的过滤查询、控制聚合层次、排序数据以及定义主从关系等。通过增加冗余存储的方式减少计算开销,提高使用效率。

11.1.3 事实表设计方法

在Kimbal 著的 The Data rehouse Toolkit-The lnitive GuidetoDimensional Modeling 一书中,对于维度模型设计采用四步设计方法:选择业务过程、声明粒度、确定维度、确定事实。
在当前的互联网大数据环境下,面对复杂的业务场景,为了更有效、准确地进行维度模型建设,基于 Kimball 的四步维度建模方法,我们进行了更进一步的改进。
第一步 选择业务过程及确定事实表类型。
在明确了业务需求以后,接下来需要进行详细的需求分析,对业务的整个生命周期进行分析,明确关键的业务步骤,从而选择与需求有关的业务过程。
以淘宝的正向订单流转为例,如图 11.1 所示。

业务过程通常使用行为动词表示业务执行的活动。比如图 11.l中的淘宝订单流转的业务过程有四个:创建订单、买家付款、卖家发货、买家确认收货。在明确了流程所包含的业务过程后,需要根据具体的业务需求来选择与维度建模有关的业务过程。比如是选择买家付款这个业务过程,还是选择创建订单和买家付款这两个业务过程,具体根据业务情况来确定。
在选择了业务过程以后,相应的事实表类型也随之确定了。比如选择买家付款这个业务过程,那么事实表应为只包含买家付款这一个业务过程的单事务事实表;如果选择的是所有四个业务过程,并且需要分析各个业务过程之间的时间间隔,那么所建立的事实表应为包含了所有四个业务过程的累积快照事实表。
第二步:声明粒度
粒度的声明是事实表建模非常重要的一步,意味着精确定义事实表的每一行所表示的业务含义,粒度传递的是与事实表度量有关的细节层次。明确的粒度能确保对事实表中行的意思的理解不会产生混淆,保证所有的事实按照同样的细节层次记录。
应该尽量选择最细级别的原子粒度,以确保事实表的应用具有最大的灵活性。同时对于订单过程而言,粒度可以被定义为最细的订单级别。比如在淘宝订单中有父子订单的概念,即一个子订单对应一种商品,如果拍下了多种商品,则每种商品对应一个子订单:这些子订单一同结算的话,则会生成一个父订单。那么在这个例子中,事实表的粒度应该选择为子订单级别。
第三步:确定维度
完成粒度声明以后,也就意味着确定了主键,对应的维度组合以及相关的维度字段就可以确定了,应该选择能够描述清楚业务过程所处的环境的维度信息。比如在淘宝订单付款事务事实表中,粒度为子订单,相关的维度有买家、卖家、商品、收货人信息、业务类型、订单时间等维度。
第四步:确定事实
事实可以通过回答“过程的度量是什么”来确定。应该选择与业务过程有关的所有事实,且事实的粒度要与所声明的事实表的粒度一致。事实有可加性、半可加性、非可加性三种类型 需要将不可加性事实分解为可加的组件。
比如在淘宝订单付款事务事实表中,同粒度的事实有子订单分摊的支付金额、邮费、优惠金额等。
第五步:冗余维度
在传统的维度建模的星形模型中,对维度的处理是需要单独存放在专门的维表中的,通过事实表的外键获取维度。这样做的目的是为了减少事实表的维度冗余,从而减少存储消耗。而在大数据的事实表模型设计中,考虑更多的是提高下游用户的使用效率,降低数据获取的复杂性,减少关联的表数量。所以通常事实表中会冗余方便下游用户使用的常用维度,以实现对事实表的过滤查询、控制聚合层次、排序数据以及定义主从关系等操作。
比如在淘宝订单付款事务事实表中,通常会冗余大量的常用维度字段,以及商品类目、卖家店铺等维度信息。

11.2 事务事实表

订单作为交易行为的核心载体,直观反映了交易的状况。订单的流转会产生很多业务过程,而下单、支付和成功完结三个业务过程是整个订单的关键节点。获取这三个业务过程的笔数、金额以及转化率是日常数据统计分析的重点,事务事实表设计可以很好地满足这个需求。本节将介绍三种不同事务事实表的设计方式,以及在淘宝交易订单中关于邮费和折扣分摊到子订单的算法。

11.2.1 设计过程

任何类型的事件都可以被理解为一种事务。比如交易过程中的创建订单、买家付款,物流过程中的揽货、发货、签收,退款中的申请退款、申请小二介入等,都可以被理解为一种事务。事务事实表, 即针对这些过程构建的一类事实表,用以跟踪定义业务过程的个体行为,提供丰富的分析能力,作为数据仓库原子的明细数据。下面以淘宝交易事务事实表为例,阐述事务事实表的一般设计过程。
( I )选择业务过程
图11.1 给出了淘宝交易订单的流转过程,其中介绍了四个重要过程:创建订单、买家付款、 卖家发货、买家确认收货,即下单、支付发货和成功完结四个业务过程。这四个业务过程不仅是交易过程中的重要时间节点 ,而且也是下游统计分析的重点,因此淘宝交易事务事实表设计着重从这四个业务过程进行展开。
Kimball 维度建模理论认为,为了便于进行独立的分析研究,应该为每个业务过程建立一个事实表。 对于是否将不同业务过程放到同一个事实表中,将在下一节 中详细介绍。
(2 )确定粒度
业务过程选定以后,就要针对每个业务过程确定一个粒度,即确定事务事实表每一行所表达的细节层次。下面先介绍淘宝订单的产生过程。
淘宝出售商品主要分两类卖家 一类是个人性质的闲置卖家,主要出售闲置的或者二手商品 一类是拥有店铺的卖家,以出售新商品为主。接下来主要以店铺类交易订单为例进行介绍。在淘宝下单交易时,有两种方式:一种是选定商品后直接购买,这样会产生一个交易订单;一种是将多种商品加入到购物车中,然后一起结算,此时对于每一种商品都会产生一个订单 ,同时对于同一个店铺会额外产生一个订单,即父订单;由于是在同一个店铺购买的,所以父订单会承载订单物流、店铺优惠等信息。而对于每一种商品产生的订单就称为子订单,子订单记录了父订单的订单号,并且有子订单标志。 如果在同一个店铺只购买了一种商品,则会将父子订单进行合并 ,只保留一条订单记录。如图 1.2 和图 1.3 所示示例。
了解了淘宝交易订单的产生过程后,现在为淘宝交易事务事实表确定粒度。如第一步所述,在淘宝交易过程中有四个重要业务过程,需要为每个业务过程确定一个粒度。其中下单、支付和成功完结三个业务过程选择交易子订单粒度 ,即每个子订单为事务事实表的一行,每个子订单所表达的细节信息为: 交易时间、卖家、买家、商品,即选择图11.2 和图 11.3 中订单 ID 1、4、5、6、7、8、9,的子订单作为事务事实表的每一行。卖家发货这个业务过程可以选择子订单粒度,即将每个子订单作为卖家发货事实表一个细节。然而,在实际操作中发现,卖家发货更多的是物流单粒度而非子订单粒度,同一个子订单可以拆开成多个物流单进行发货。在事务事实表设计过程中,秉承确定为最细粒度的原则,因此对于卖家发货确定为物流单粒度,和其他三个业务过程不同,这样可以更好地给下游统计分析带来灵活性。


(3 )确定维度
选定好业务过程并且确定粒度后,就可以确定维度信息了。在淘宝交易事务事实表设计过程中,按照经常用于统计分析的场景,确定维度包含:买家、卖家、商品、商品类目、发货地区、收货地区、父订单维度以及杂项维度。由于订单的属性较多,比如订单的业务类型、是否无线交易、订单的 attributes 属性等,对于这些使用较多却又无法归属到上述买卖家或商品维度中的属性,则新建一个杂项维度进行存放,如图 1.4 所示。
(4 )确定事实
作为过程度量的核心,事实表应该包含与其描述过程有关的所有事实。以淘宝交易事务事实表为例,选定一个业务过程一一下单、支付和成功完结,不同的业务过程拥有不同的事实。比如在下单业务过程中,需要包含下单金额、下单数量、下单分摊金额;在支付业务过程中,包含支付金额、分摊邮费、折扣金额、红包金额、积分金额;在完结业务过程中包含确认收货金额等。由于粒度是子订单,所以对于一些父订单上的金额需要分摊到子订单上,比如父订单邮费、父订单折扣等。具体的分摊算法将在“父子事实的处理方式” 一节中介绍。
根据 Kimball 维度建模理论,经过以上四步,淘宝交易事务事实表已成型,可以满足下游分析统计的需要。然而,阿里巴巴数据仓库在建模时,基于以上四步增加了一步一一退化维度,这个过程在 Kimball度建模中也有所提及;但阿里巴巴数据仓库出于效率和资源的考虑,将常用维度全部退化到事实表中,使下游分析使用模型更加方便。
(5 )冗余维度
在确定维度时,包含了买卖家维度、商品维度、类目维度 、收发货维度等,Kimball 维度建模理论建议在事实表中只保存这些维表的外键,而淘宝交易事务事实表在 Kimball 维度建模基础之上做了进一步的优化,将买卖家星级、标签、店铺名称、商品类型、商品特征、商品属性、类目层级等维度属性都冗余到事实表中,提高对事实表进行过滤查询、统计聚合的效率,如图 1.5 所示
经过以上五个步骤,完成了淘宝交易事务事实表的设计。
但在设计过程中遗留一个问题,即对于单一事实表中是否包含多个业务过程,还没有给出定论。接下来将通过在淘宝和 1688 交易过程中采用不同的设计方案来阐述两种设计方法。

11.2.2 单事务事实表

单事务事实表,顾名思义,即针对每个业务过程设计一个事实表。这样设计的优点不言而喻,可以方便地对每个业务过程进行独立的分析研究。 1688 交易流程则采用这种模式构建事务事实表。
1688 交易和淘宝交易相似,主要流程也是下单、支付、发货和完结,而在这四个关键流程中 1688 交易选择下单和支付两个业务过程设计事务事实表,分别是 1688 交易订单下单事务事实表 1688 交易订单支付事务事实表。
选定业务过程后,将对每个业务过程确定粒度、维度和事实。对于1688 交易订单下单事务事实表,确定子订单粒度,选择买家、卖家、商品、父订单、收货地区维度,事实包含下单分摊金额和折扣金额,如图11.6 所示:而对于 1688 交易订单支付事务事实表 ,粒度和维度与交易订单下单事务事实表相同,所表达的事实则不一样 ,包含支付金额、支付调整金额和支付优惠等, 如图 11.7 所示。
1688 交易针对下单和支付分别建立单事务事实表后,每天的下单记录则进入当天的下单事务事实表中,每天的支付记录进入当天的支付事务事实表中,由于事实表具有稀疏性质 ,因此只有当天数据才会进入当天的事实表中。下面以具体交易订单为例 ,展示单事务事实表的设计实例。如图 1.8 所示, orderl 2016-01-01 下单并且在当天完成支付;order2和order3 2016-01-01 下单并且在 2016-01-02 完成支付。如图11.9 和图11. 10所示, order1、order2、order3 写入下单事务事实表中,业务日期(下单日期)均为 2016-01-01; orderl order2和order3 也分别写人支付事务事实表中,业务日期(支付日期)分别为2016 01-01 2016-01-02


11.2.3 多事务事实表

多事务事实表将不同的事实放到同一个事实表中,即同一个事表包含不同的业务过程。多事务事实表在设计时有两种方法进行事实的处理 ①不同的业务过程的事实使用不同的事实字段进行存放:①不同业务过程的事实使用同一个事实字段进行存放,但增加一个业务过程标签。接下来将通过淘宝交易事务事实表和淘宝收藏商品事务事实表分别阐述其设计方法。
1.淘军交易事务事实表
淘宝交易事务事实表采取将不同业务过程的事实使用不同事实字段进行存放的设计模式。淘宝交易事务事实表中同时包含了下单、支付和成功完结三个业务过程,这三个业务过程拥有相同的粒度,都是子订单粒度,也比较适合放到同一个事实表中。选择业务过程时没有把发货也加到此事务事实表中,原因是发货的粒度比子订单更细,属于不同粒度上的业务过程,因此没有放到同一个事实表中。
在确定好业务过程和粒度后,下一步就是确定维度和事实。对于不同的业务过程和粒度,一般而言,维度也不完全一致。但是在设计淘宝交易事务事实表时,根据分析统计 ,常用维度比较一致 ,因此在维度层面可以保证这三个业务过程放到同一个事务事实表中。这里的维度也是在交易过程中比较常见的,如包括买家、卖家、商品、类目、店铺、收发货地区等,无论在哪一个业务过程中,都需要按照这些维度进行统计分析。
将多个业务过程放到同一个事实表中,将要面对的是如何处理多个事实。淘宝交易事务事实表中包含了下单 、支付和成功完结三个业务过程,则需要包含下单度量、支付度量和成功完结度量信息 ,这里的解决方案是针对每个度量都使用一个字段进行保存 ,即不同的事实使用不同的字段进行存放;如果不是当前业务过程的度量,则采取零值处理方式。比如在下单业务过程中,对于支付度量和成功完结度量全部置为 ,其他业务过程类似处理。
同一个事实表中包含了多个业务过程,在表中如何进行标记呢?淘宝交易事务事实表采取了这样的解决方案,即针对每个业务过程打标签,标记当天是否是这个业务过程,比如针对下单,则打一个是否当天下单的标签;针对支付,打一个是否当天支付的标签;针对成功完结,打一个是否当天成功完结的标签 ,标签之间互不相干。淘宝交易事务事实表如图 1.11 示。
同样以具体交易订单为例,展示多事务事实表的设计实例,如图11.12 所示, order 2016-01-01 下单并且在当天完成支付 order2
order3 2016-01-01 下单并且在 2016-01-02 完成支付,在2016-01-04成功完结。淘宝交易多事务事实表数据 例如图 1.13 ,同 一个事实表中包含有多个业务过程数据。


2.淘宝收藏商品事务事实表
收藏和加购物车是淘宝购物过程中比较常见的两个行为,当用户遇到喜欢的商品或者店铺时可以选择收藏,然后下次继续浏览购买。这里以收藏事务事实表阐述多事务事实表在处理不同业务过程时使用同一个字段保存事实的设计方式。
收藏业务较为简单,商品和店铺的收藏业务相似,这里仅以收藏商品为例进行阐述。 用户可以直接收藏一个商品,也可以删除所收藏的商品,所以在这个过程中包含了两个业务过程 收藏商品和删除商品。因此收藏商品事务事实表的第一步就是选择收藏商品和删除商品两个业务过程。 业务过程确定后,接下来就是确定粒度。无论是收藏商品还是删除所收藏的商品,都是用户对商品的一个操作,因此这里确定为用户加上商品的粒度。
确定好业务过程和粒度后,接下来是确定维度和事实。由于粒度是用户加上商品,所以维度主要是用户维度和商品维度。为了使事实表信息更丰富,冗余了商品类目维度和商品所属卖家维度,收藏商品和删除商品业务过程所属的维度是一致的。
收藏商品和删除商品是两个不同的业务过程,但是确定了相同的粒度和维度 ,所以考虑、设计多事务事实表 ,将这两个业务过程放到同一个事实表中 ,只是在不同业务过程的事实上进行区分。在前面的“淘宝交易事务事实表”中是使用不同字段存放不同业务过程的事实,这里的解决方案是使用同一个字段存放不同业务过程的事实,使用标签字段区分不同业务过程,比如收藏事务事实表使用一个“收藏事件类型”字段来区分是收藏商品还是删除商品。收藏商品和删除商品的事实主要是商品价格,不过收藏事务事实表更多的是无事实的事实表,一般用于统计收藏或者删除的次数。
下面通过实例来说明收藏商品事务事实表的设计过程,如图 11.4、11.15 所示。


3. 多事务事实表的选择
上面介绍了两种多事务事实表的设计方式,在实际应用中要根据业务过程进行选择。由于是多事务事实表,因此在事实表中包含多个业务过程
● 当不同业务过程的度量比较相似、差异不大时,可以采用第二种多事务事实表的设计方式,使用同一个字段来表示度量数据。但这种方式存在一个问题一一在同一个周期内会存在多条记录。
● 当不同业务过程的度量差异较大时,可以选择第一事务事实表的设计方式,将不同业务过程的度量使用不同字段冗余到表中,非当前业务过程则置零表示。这种方式所存在的问题是度量字段零值较多。

11.2.4 两种事实表对比

前面介绍了单事务事实表和多事务事实表的设计过程,同时给出了关于 1688 和淘宝不同事务事实表的实例。目前两类事实表都有实际的应用,但具体哪一种设计方式更优,我们接下来进行分析。
1. 业务过程
对于单事务事实表,一个业务过程建立一个事实表,只反映一个业务过程的事实对于多事务事实表,在同一个事实表中反映多个业务过程。多个业务过程是否放到同一个事实表中,首先需要分析不同业务过程之间的相似性和业务源系统。比如淘宝交易的下单、支付和成功完结这三个业务过程是存在相似性的,都属于订单处理中的一环,并且都来自于交易系统 ,因此适合放到同一个事务事实表中。
2.粒度和维度
在考虑是采用单事务事实表还是多事务事实表时,另一个关键点就是粒度和维度,在确定好业务过程后,需要基于不同的业务过程确定粒度和维度,当不同业务过程的粒度相同,同时拥有相似的维度时,此时就可以考虑采用多事务事实表。 如果粒度不同,则必定是不同的事实表。比如交易中支付和发货有不同的粒度,则无法将发货业务过程放到淘宝交易事务事实表中。
3. 事实
对于不同的业务过程,事实往往是不同的,单事务事实表在处理事实上比较方便和灵活,仅仅体现同一个业务过程的事实即可而多事务事实表由于有多个业务过程, 所以有更多的事实需要处理。如果单一业务过程的事实较多,同时不同业务过程的事实又不相同,则可以考虑使用单事务事实表,处理更加清晰;若使用多事务事实表, 会导致事实表零值或空值字段较多。
4.下游业务使用
单事务事实表对于下游用户而言更容易理解 关注哪个也务过程就使用相应的事务事实表;而多事务事实表包含多个业务过程,用户使用时往往较为困惑。 1688 和淘宝交易分别采用了这两种方式,从日常使用来看,对于淘宝交易事务事实表下游用户确实有一定的学习成本。
5. 计算存储成本
针对多个业务过程设计事务事实表,是采用单事务事实表还是多事务事实表,对于数据仓库的计算存储成本也是参考点之一,当业务过程数据来源于同一个业务系统,具有相同的粒度和维度,且维度较多而事实相对不多时,此时可以考虑使用多事务事实表,不仅其加工计算成本较低,同时在存储上也相对节省,是一种较优的处理方式。
两种事务事实表的比较如表 1.2 所示。

11.2.5 父子事实的处理方式

淘宝交易父子订单的含义在前文确定粒度时有所说明,在同一个店铺同时下单多种商品,不仅每种商品有一个子订单,而且这几个子订会再单独产生一个父订单。下单和支付都是在父订单粒度上完成的,比如拍下时的订单总额、支付总额、支付邮费,淘宝交易事务事实表在粒度选择上,按照粒度最细原则,确定为子订单,因此需要将下单总额或者支付总额分摊到每个子订单上,当然只有一个子订单时是不需要进行分摊的。下面以子订单分摊的有效下单金额和支付金额为例加以说明。

子订单下羊全额=丁羊商品数量×商品价格
子订单分摊的有效下羊全额=下羊商品数量 商品价格+义订单邮费
单分摊比例一子订单折扣一义订单折扣 下羊分摊比例
下单分摊比例=(下单商品数量×原价一子订 单折扣) um (下羊商品数量×
原价一子订单折扣)
子订单分摊的支付金额=父订单支付金额×支付分摊比例
支付分摊比例=(下单商品数量×原价一子订 单折扣+调价) sum (下单商品
数量×原价一子订单折扣+调价)

通过分摊父订单的金额将所有业务过程的度量全部带进淘宝交易事务事实表中 ,包括下单数量、商品价格、子订单折扣、下单分摊比例、父订单支付金额、父订单支付邮费、父订单折扣、子订单下单金额、子订单下单有效金额、支付分摊比例、子订单支付金额等,将父子事实同时冗余到事务表中。

11.2.6 事实的设计准则

1.事实完整性
事实表包含与其描述的过程有关的所有事实,即尽可能多地获取所有的度量。在淘宝交易事务事实表中,比如支付业务过程,在子订单粒度上的支付金额、支付邮费、支付红包、支付积分、支付折扣都有所包含,覆盖全面。
2. 事实一致性
在确定事务事实表的事实时,明确存储每一个事实以确保度量的一致性。以淘宝交易事务事实表为例 ,在下单业务过程中,有下单商品数量和商品价格两个事实,但在事实表中计算了下单金额和下单有效金额,它们可以通过商品数量乘以商品价格进行计算。虽然下游在取数时也可以通过这种方式完成计算,但是在事实表中统一计算可以保证度量的一致性,其他如支付过程中的分摊金额等也是类似的。
3.事实可加性
事实表确定事实时,往往会遇到非可加性度量 ,比如分摊比例、利润率等,虽然它们也是下游分析的关键点,但往往在事务事实表中关注更多的是可加性事实,下游用户在聚合统计时更加方便。在淘宝交易事务事实表中,存储了分摊比例这样的度量,但更多的是存储各类金额的度量。

11.3 周期快照事实表

前面章节对事务事实表进行了详细的阐述,同时给出了淘宝交易事务事实表的设计过程。事务事实表可以很好地跟踪一个事件,并对其进行度量,以提供丰富的分析能力。然而,当需要一些状态度量时,比如账户余额、买卖家星级、商品库存、卖家累积交易额等,则需要聚集与之相关的事务才能进行识别计算;或者聚集事务无法识别 ,比如温度等。对于这些状态度量,事务事实表是无效率的,而这些度量也和度量事务本身一样是有用的 ,因此, 维度建模理论给出了第二种常见的事实表一一周期快照事实表,简称“快照事实表”。快照事实表在确定的间隔内对实体的度量进行抽样,这样可以很容易地研究实体的度量值,而不需要聚集长期事务历史。接下来将以淘宝交易结束后的评价数据、卖家的累积支付金额、买卖家星级等事实表的设计为例,介绍快照事实表在阿里巴巴数据仓库中的设计与应用。

11.3.1 特性

快照事实表的设计有一些区别于事务事实表设计的性质。事务事实表的粒度能以多种方式表达,但快照事实表的粒度通常以维度形式声明;事务事实表是稀疏的,但快照事实表是稠密的;事务事实表中的事实是完全可加的,但快照模型将至少包含一个用来展示半可加性质的事实。
1. 用快照采样状态
快照事实表以预定的间隔采样状态度量。这种间隔联合一个或多个维度,将被用来定义快照事实表的粒度,每行都将包含记录所涉及状态的事实。
现在以淘宝交易卖家自然年汇总事实表为例进行介绍。淘宝活动运营小二或者卖家经常都需要看一些交易状态数据,比如自然年至今或者历史至今的下单金额、支付金额、支付买家数、支付商品件数等状态度量,对于卖家而言 ,可能每天早上都想看下截至昨天的成交情况;对于小二 ,可能在频繁的活动周期就需要查看一次成交情况。这些状态度量可以每天通过事务事实表进行聚集,但随着时间跨度变大聚集效率会越来越低 ,因此需要设计快照事实表进行状态的度量,这里用于采样的周期间隔是每天,如图 11.16 所示的快照事实表记录了每个卖家的下单和支付情况。
2. 快照粒度
事务事实表的粒度可以通过业务过程中所涉及的细节程度来描述,但快照事实表的粒度通常总是被多维声明,可以简单地理解为快照需要采样的周期以及什么将被采样。在淘宝交易卖家快照事实表中,粒度可以被理解为每天针对卖家的历史截至当日的下单支付金额进行快照。
当然,快照周期不一定都按天来进行,也可以按照月或者季度来统计。比如淘宝交易有针对卖家加类目的每月汇总事实表,每月统计一次,同时维度也不仅一个,包含了卖家和类目。
3. 密度与稀疏性
快照事实表和事务事实表的一个关键区别在密度上。事务事实表是稀疏的,只有当天发生的业务过程,事实表才会记录该业务过程的事实,如下单、支付等;而快照事实表是稠密的,无论当天是否有业务过程发生,都会记录一行,比如针对卖家的历史至今的下单和支付金额,无论当天卖家是否有下单支付事实,都会给该卖家记录一行。稠密性是快照事实表的重要特征,如果在每个快照周期内不记录行,比如和事务事实表一样 ,那么确定状态将变得非常困难。
4.半可加性
在快照事实表中收集到的状态度量都是半可加的。与事务事实表的可加性事实不同,半可加性事实不能根据时间维度获得有意义的汇总结果。比如对于淘宝交易事务事实表,可以对一个周期内的下单金额或者支付金额进行汇总,得到下单支付总额,但快照事实表在每个采样周期内是不能对状态度量进行汇总的。比如淘宝交易卖家快照事实表,无法对每天的历史至今的下单金额进行汇总,也没有汇总意义。虽然不能汇总,但可以计算一些平均值,比如计算每天一个下单的平均值。

11.3.2 实例

阿里巴巴数据仓库建模时,针对不同的业务场景,事务事实表无法满足所有的需求。正如上一节所介绍的,在统计历史至今的卖家或者类目的下单金额和支付子订单数时,通过事务事实表聚集效率较低,而采用周期快照事表则是可行的方案。接下来主要介绍阿里巴巴数据仓库周期快照事实表的设计过程。
通过上一节对快照事实表的特性介绍,对于快照事实表的设计步骤可以归纳为:
● 确定快照事实表的快照粒度。
● 确定快照事实表采样的状态度量。
下面将依照该设计步骤介绍几类常见的快照事实表。
1. 单维度的每天快照事实表
(1 )确定粒度
采样周期为每天,针对卖家、买家、商品、类目 、地区等维度的快照事实表 ,比如淘宝卖家历史至今汇总事实表、淘宝商品自然月至今汇总事实 ,不同的采样粒度确定了不同的快照事实表。
(2 )确定状态度量
确定好粒度以后,就要针对这个粒度确定需要采样的状态度量。比如淘宝卖家历史至今汇总事实表,包含了历史截至当日的下单金额、历史截止当日的支付金额等度量,如图11.17所示。
淘宝商品历史至今快照事实表,确定了商品维度和商品状态度量如图11.18 所示。

2. 混合维度的每天快照事实表
混合维度相对于单维度,只是在每天的采样周期上针对一个维度进行采样。比如淘宝买卖家历史至今快照事实 ,采样周期依然是每天,维度是卖家加买家,反映的是不同买家对于不同卖家的下单支付金额如图 1.19 所示。

以上两类快照事实表都有一个特点一一都可以从事务事实表进行汇总产出,这是周期快照事实表常见的一种产出模式。除此之外,还有一种产出模式,即直接使用操作型系统的数据作为周期快照事实表的数据源进行加工,比如淘宝卖家星级、卖家 DSR 事实表等。下面介绍这类事实表的设计过程。
● 淘宝卖家信用分和 DSR 快照事实表
在介绍这类事实表之前,首先介绍淘宝卖家服务评价系统。在淘宝店铺交易成功以后会进行一次好中差评以及 DSR 评价(包括物流服务、描述相符和服务态度),淘宝卖家信用就是基于好中差评计算得出的,DSR 评分会累积计算一个综合分;天猫店铺交易完成以后仅有 DSR评价,默认都是好评,如图 11.20 、图 11.21 所示。

其中淘宝卖家信用是通过好中差评的次数进行计算的 ,具体为:好评加一分,中评零分,差评扣一分然后累积最终的得分,得到卖家的信用,如图 11.20 所示的卖家信用分是 25318 DSR 评分是通过分项的星级综合得到最终的评分,其中描述相符、服务态度和物流服务都是1~5星的打分方式,综合每一个星级的买家数得到最终的一个平均分,具体为:( 1星× 1星人数+2 星× 2星人数+ 3星× 3星人数+4 星× 4星人数+5星× 5星人数) /(1 星人数十2 星人数+ 3星人数+4 星人数+ 5星人数)。
前面所述的卖家信用分和 DSR 评分都是在操作型系统中计算完成的,阿里巴巴数据仓库关于淘宝卖家信用分和 DSR 快照事实表是直接采用操作型系统数据进行设计加工,采样周期是每天,针对卖家维度的统计,状态度量就是卖家信用分和 DSR 评分,如图 11.22 所示。
3. 全量快照事实表
阿里巴巴数据仓库在设计快照事实表时,还有一类特殊的快照事实表,即全量快照事实表,这类事实表的特性与前面所述的快照事实表有一些差异,但依然属于周期快照事实表范畴。下面还是以淘宝好中差评快照事实表为例来阐述该类事实表的设计方法。
( 1 )确定粒度
淘宝好中差评每天都在变化,下游统计分析也是每天都在进行的,因此确定采样周期是每天。这里的采样维度比较特殊,是针对评价本身,即每天按照评价进行采样的,每一条好中差评价就是快照事实表的最细粒度。
(2 )确定状态度量
对于好中差评价的度量关注更多的是评价本身,即没有类似于金额、商品数这样的度量,因此设计为无事实的事实表,更多关注评价的状态。
对于全量快照事实表,这里再增加一步,即冗余维度。此如好中差评快照事实表,冗余了子订单维度、商品维度、评论者维度、被评论者维度以及杂项维度 ,包括评论内容、是否匿名等信息,如图 11.23 所示。

11.3.3 注意事项

1. 事务与快照成对设计
数据仓库维度建模时,对于事务事实表和快照事实表往往都是成对设计的 ,互相补充,以满足更多的下游统计分析需求,特别是在事务事实表的基础上可以加工快照事实表,如前面所述的淘宝卖家历史至今快照事实表,就是在事务事实表的基础上加工得到的,既丰富了星形模型,又降低了下游分析的成本。
2. 附加事实
快照事实表在确定状态度量时,一般都是保存采样周期结束时的状态度量。但是也有分析需求需要关注上一个采样周期结束时的状态度量,而又不愿意多次使用快照事实表,因此一般在设计周期快照事实表时会附加一些上一个采样周期的状态度量。
3. 周期到日期度量
在介绍淘宝卖家历史至今快照事实表时,指定了统计周期是卖家历史至今的一些状态度量,比如历史截至当日的下单金额、成交金额等。然而在实际应用中,也有需要关注自然年至今、季度至今、财年至今的一些状态度量,因此在确定周期快照事实表的度量时,也要考虑类似的度量值,以满足更多的统计分析需求。阿里巴巴数据仓库在设计周期快照事实表时,就针对多种周期到日期的度量设计了不同的快照事实表,比如淘宝卖家财年至今的下单金额、淘宝商品自然年至今的收藏次数等。

11.4 累积快照事实表

针对淘宝交易,设计了淘宝交易下单/支付/确认收货事务事实表,用于统计下单/支付/确认收货的子订单数、 GMV 等。但仍然有很多需求,此事务事实表很难满足,比如统计买家下单到支付的时长、买家支付到卖家发货的时长、买家从下单到确认收货的时长等。如果使用事务事实表进行统计,则逻辑复杂且性能很差。对于类似于研究事件之间时间间隔的需求,采用累积快照事实表可以很好地解决。

11.4.1 设计过程

对于累积快照事实表,其建模过程和事务事实表相同,适用于维度建模的步骤。下面详述淘宝交易累积快照事实表的设计过程,并讨论和事务事实表的设计差异。
第一步 选择业务过程。在“事实表基础”一节中讲解了淘宝交易订单的流转过程,主要有四个事件,即买家下单、买家支付、卖家发货、买家确认收货业务过程。对于这四个业务过程,在事务统计中只关注下单、支付和确认收货三个业务过程;而在统计事件时间间隔的需求中,卖家发货也是关键环节。所以针对淘宝交易累积快照事实表,我们选择这四个业务过程。
第二步:确定粒度。在“事务事实表”中提到,对于淘宝交易,业务需求一般是从子订单粒度进行统计分析,所以选择子订单粒度。淘宝交易事务事实表的粒度也是子订单,但通常对于子订单的每个事件都会记录一行,对于多事件事实表,如果子订单同一周期发生多次事件则记录一行;而对于累积快照事实表,用于考察实体的唯一实例,所以子订单在此表中只有一行记录,事件发生时,对此实例进行更新。
第三步:确定维度。与事务事实表相同,维度主要有买家、卖家、店铺、商品、类目、发货地区、收货地区等。四个业务过程对应的时间字段,格式为日期+时间,分别为下单时间、支付时间、发货时间、确认收货时间,对应于日期维表,图11.24 中未标识。在实际使用时会使用视图或 SQL 别名的方式表示四个日期角色维度,类似于发货地区维度和收货地区维度。
在交易订单表中,存在很多与订单相关的属性,如订单类型、子类型、支付状态、物流状态、 attributes、options 等。对于类似的属性字段,无法归属到已有的商品等维度中,所以新建杂项维度存放。在数据仓库建模理论中,杂项维度无自然键,一般是枚举值的组合 ,对于每个组合生成一个代理键。但在实际建模中,存在很多非枚举值 ,且对于每个订单都不相同,如订单的 attributes、options 属性。所以实际中杂项维度设计时,也可以直接使用自然键标识具体的维度值,如图11.24 中所示的子订单维度和父订单维度。

第四步:确定事实。对于累积快照事实表,需要将各业务过程对应的事实均放人事实表中。比如淘宝交易累积快照事实表,包含了各业务过程对应的事实,如下单对应的下单金额,支付对应的折扣、邮费和支付金额,确认收货对应的金额等。累积快照事实表解决的最重要的问题是统计不同业务过程之间的时间间隔,建议将每个过程的时间间隔作为事实放在事实表中。在淘宝交易累积快照事实表建模中,由于每个过程的时间间隔计算逻辑简单,因此并未加人事实表中,如图11.25 所示。
第五步:退化维度。在大数据的事实表模型设计中,更多的是考虑提高下游用户的使用效率,降低数据获取的复杂性,减少关联的表数量。一方面,存储成本降低了,而相比之下 CPU 成本仍然较高;另一方面,在大数据时代,很多维表比事实表还大,如淘宝几十亿的商品、几亿的买家等,在分布式数据仓库系统中,事实表和维表关联的成本很高。所以在传统的维度模型设计完成之后,在物理实现中将各维度的常用属性退化到事实表中,以大大提高对事实表的过滤查询、统计聚合等操作的效率,具体详情不再赘述。

11.4.2 特点

1.数据不断更新
事务事实表记录事务发生时的状态,对于实体的某一实例不再更新;而累积快照事实表则对实体的某一实例定期更新。以淘宝交易为例,
11.3 11.4 11.5 通过实例展示了事务事实表的情况,假设采用多事务事实表:对于 order1订单, 2015-11-12 支付后,产生新的支付记录, 2015-11-11 的数据不会更新。截至 2015-11-13 ,买家确认收货后,共产生3条记录。
2015-11-11 下单,如表 11.3 所示。
2015-11-12 支付,如表 11.4 所示。

2015-11-13 确认收货,如表 11.5 所示。
对于累积快照事实表,则只有一条记录,针对此记录不断更新,如11.6 所示。
2. 多业务过程日期
累积快照事实表适用于具有较明确起止时间的短生命周期的实体,比如交易订单、物流订单等,对于实体的每一个实例,都会经历从诞生到消亡等一系列步骤。对于商品、 用户等具有长生命周期的实体,采用周期快照事实表更合适。
累积快照事实表的典型特征是多业务过程日期,用于计算业务过程之间的时间间隔 。但结合阿里巴巴数据仓库模型建设的经验,对于累积快照事实表,还有一个重要作用是保存全量数据。对于淘宝交易,需要保留历史截至当前的所有交易数据,其中一种方式是在 ODS 层保留和源系统结构完全相同 的数据 但由于使用时需要关联维度,较为麻烦,所以在公共明细层需要保留一份全量数据,淘宝交易累积快照事实表就承担了这样的作用一一存放加工后的事实,并将各维度常用属性和订单杂项维度退化到此表中。通常用于数据探查、统计分析、数据挖掘等。

11.4.3 特殊处理

1.非线性过程
如前面章节所提到的,淘宝交易流程一般经过如下四个业务过程
下单→支付→发货→确认收货
但并不是所有的交易都会走此流程。比如买家下单之后不支付,可以自己关闭订单或者经过一段时间后系统自动关闭订单。此时交易流程如下:下单→关闭订单
买家下单并支付之后,可以申请退款,卖家同意后,交易关闭。此时交易流程如下:
下单→支付→关闭订单
在特殊情况下,流程可能会回转。比如在退款过程中,正常流程可能是
买家申请退款→卖家同意退款→退款达成
或者
买家 申请退款→卖家不同意退款→退款关关闭
但由于买家和卖家之间未达成协议,卖家不同意买家的退款,此时流程可能是:
买家申请退款→卖家不同意退款→买家申请退款→卖家不同意退
…一直到退款达成或关闭
针对非线性过程,处理情况主要有以下几种。
( 1 )业务过程的统一
比如流程结束标志的统 ,最开始设计交易累积快照事实表时,以交易完成作为结束标志;进一步了解业务之后,发现交易关闭也是交易结束的一个分支,所以将交易结束作为流程结束、实体消亡的标志,包括交易完成和交易结束两种情况。
(2 )针对业务关键里程碑构建全面的流程
比如淘宝交易,全流程可能是下单→支付→发货→确认收货。对于没有支付或没有发货的交易订单,全流程仍然可以覆盖,相关业务过程的时间字段和事实置空。
(3 )循环流程的处理
主要问题是解决一个业务过程存在多个里程碑日期的问题。使用业务过程第一次发生的日期还是最后一次发生的日期,决定权在商业用户,而不是设计或开发人员。
2. 多源过程
针对多业务过程建模时,业务过程可能来自于不同的系统或者来源于不同的表,其对于累积快照事实表的模型设计没有影响,但会影响ETL 开发的复杂程度。对于淘宝交易累积快照事实表,除了上述提到的下单→支付→发货→确认收货流程,假设需要关注交易子订单退款业务或者物流业务, 时会涉及交易、售后、物流 个业务源系统。
退款业务流程如下
下单→支付→买家申请退款→卖家同意退款 退款达成→交易关闭
或者
下单 →支付→发货 →买家 申请退款→卖家同意退款→退款达成→交易关闭
或者
下单 →支付→发货→买家申请退款→ 卖家不同意退款→退款取消→交易成功
针对多源业务建模,主要考虑事实表的粒度问题。对于淘宝交易累积快照事实表,其粒度是交易子订单。对于退款,由于每个子订单可能存在多次退款,此时如果要将退款相关业务过程加入模型中,则需要和商业用户确定存在多次退款时如何取舍,确保模型粒度不变。
3.业务过程取舍
上一节提到的退款业务流程是简化的,比较完整的业务流程如下:
申请退款→申请小二介入→小二实际介入→卖家同意退款→退款完结
将退款相关业务流程设计进入交易累积快照事实表时 ,是否需要所有的业务过程?答案是否定的。当拥有大量的业务过程时,模型的实现复杂度会增加,特别是对于多源业务过程,模型的精合度过高,此时需根据商业用户需求,选取关键的里程碑。

11.4.4 物理实现

逻辑模型和物理模型密不可分,针对累积快照事实表模型设计,其有不同的实现方式。
第一种方式是全量表的形式。 此全量表一般为日期分区表 ,每天的分区存储昨天的全量数据和当天的增量数据合并的结果,保证每条记录的状态最新。 此种方式适用于全量数据较少的情况。如果数据量很大,此全量表数据量不断膨胀,存储了大量永远不再更新的历史数据,对ETL 和分析统计性能影响较大。

第二种方式是全量表的变化形式。此种方式主要针对事实表数据量很大的情况。较短生命周期的业务实体一般从产生到消亡都有一定的时间间隔,可以测算此时间间隔,或者根据商业用户的需求确定一个相对较大的时间间隔。比如针对交易订单,我们以 200 天作为订单从产生到消亡的最大间隔。设计最近 200 天的交易订单累积快照事实表,每天的分区存储最近 200 天的交易订单 200 天之前的订单则按照 gmt_create建分区存储在归档表中。此方式存在的一个问题是 200 天的全量表根据商业需求需要保留多天的分区数据,而由于数据量较大,存储消耗较大。
第三种方式是以业务实体的结束时间分区。每天的分区存放当天结束的数据,设计一个时间非常大的分区,比如 3000-12-31 ,存放截至当前未结束的数据。由于每天将当天结束的数据归档至当天分区中,时间非常大的分区数据量不会很大, ETL 性能较好;并且无存储的浪费,于业务实体的某具体实例,在该表的全量数据中唯一。 比如对于交易订单,在交易累积快照事实表中唯一。

针对第三种方式,可能存在极特殊情况,即业务系统无法标识业实体的结束时间。比如业务系统调用接口很多,依赖的系统复杂,最终无法判断业务实体是否已经消亡。 如菜鸟的物流订单, 由于其依赖物公司的数据,和大量的物流公司存在接口,按照约定,物流公司会向采鸟回传运单的流转信息,但无法保证 100% 准确;且一般为批量回传,菜鸟订单系统根据批量数据更新物流订单的结束标志几乎无法实现。前台业务系统没有物流订单的结束时间,那么如何设计物流订单累积快事实表昵?针对此问题,可以有两种处理方式。

第一种方式 ,使用相关业务系统的业务实体的结束标志作为此业务系统的结束标志。比如针对物流订单,可以使用交易订单。理论上交易订单完结了,则物流订单已经完结。

第二种方式 ,和前端业务系统确定口径或使用前端归档策略。累积快照事实表针对业务实体一般是具有较短生命周期的,和前端业务系统确定口径,确定从业务实体的产生到消亡的最大间隔。另外,针对大量的事实数据,前端系统会定期对历史数据进行归档,避免业务库性能的下降,对于这种情况,可以使用前端系统的归档时间作为业务实体的结束日期。

11.5 三种事实表的比较

通过前面章节的介绍,我们对数据仓库三种事实表有了详细的了解。一些业务过程可能只需要一种事实表,而另外一些业务过程可能需要两种或三种事实表。三种事实表相互补充,给出业务的完整描述。表11.7 对三种事实表进行了比较。

事务事实表记录的事务层面的事实,用于跟踪业务过程的行为,并支持几种描述行为的事实,保存的是最原子的数据,也称为“原子事实表”。事务事实表 中的数据在事务事件发生后产生,数据的粒度通常是每个事务一条记录。 一旦事务被提交,事实表数据被插人,数据就不能更改,其更新方式为增量更新。

周期快照事实表以具有规律性的、可预见的时间间隔来记录事实,如余额、库存、层级、温度等,时间间隔为每天、每月、每年等,典型的例子如库存日快照表等。周期快照事实表的日期维度通常记录时间段的终止日,记录的事实是这个时间段内一些聚集事实值或状态度量。事实表的数据一旦插人就不能更改,其更新方式为增量更新。
累积快照事实表被用来跟踪实体的一系列业务过程的进展情况 ,它通常具有多个日期字段,用于研究业务过程中的里程碑过程的时间间隔。另外,它还会有一个用于指示最后更新日期的附加日期宇段。由于事实表中许多日期在首次加载时是不知道的,而且这类事实表在数据加载完成后,可以对其数据进行更新,来补充业务状态变更时的日期信息和事实。

11.6 无事实的事实表

在维度模型中,事实表用事实来度量业务过程,不包含事实或度量的事实表称为“无事实的事实表”虽然没有明确的事实,但可以用来支持业务过程的度量。
常见的无事实的事实表主要有如下两种:
第一种是事件类的,记录事件的发生。在阿里巴巴数据仓库中,最常见的是日志类事实表。比如用户的浏览日志,某会员某时间点浏览了淘宝首页、某会员某时间点浏览了某卖家的店铺中的某商品详情页等对于每次点击,其事实为1,但一般不会保存此事实。
第二种是条件、范围或资格类的,记录维度与维度多对多之间的关系。比如客户和销售人员的分配情况、产品的促销范围等。

11.7 聚集型事实表

数据仓库的性能是数据仓库建设是否成功的重要标准之一。聚集主要是通过汇总明细粒度数据来获得改进查询性能的效果。通过访问聚集数据,可以减少数据库在响应查询时必须执行的工作量,能够快速响应用户的查询,同时有利于减少不同用户访问明细数据带来的结果不一致问题。尽管聚集能带来良好的收益,但需要事先对其进行加载和维护这将会对给 ETL 带来更多的挑战。

阿里巴巴将使用频繁的公用数据,通过聚集进行沉淀,比如卖家最近一天的交易汇总表、卖家最近N天的交易汇总表、卖家自然年交易汇总表等。这类聚集汇总数据,被叫作“公共汇总层”。

在本节中,前半部分将会介绍聚集的基本原理和通用步骤,这些都是在建设聚集型事实表时必须明白的事情后半部分将会介绍阿里巴巴建设公共汇总层的一些实践。

11.7.1 聚集的基本原则

● 一致性。聚集表必须提供与查询明细粒度数据一致的查询结果。从设计角度来看,确保一致性,最简单的方法是确保聚集星形模型中的维度和度量与原始模型中的维度和度量保持一致。

● 避免单一表设计。不要在同一个表中存储不同层次的聚集数据否则将会导致双重计算或出现更糟糕的事情。在聚集表中有些行存放按天汇总的交易额,有些行存放按月汇总的交易额 这将会让使用者产生误用导致重复计算。为了避免此类问题,通用的做法是在聚集时显式地加人数据层级列以示区别,但是这样会加大使用者的使用成本。行之有效的另一种方法是把按天与按月汇总的交易额用两列存放,但是需要在列名或者列注释上能分辨出来。
● 聚集粒度可不同。聚集并不需要保持与原始明细粒度数据一样的粒度,聚集只关心所需要查询的维度。订单涉及的维度有商品、买家、卖家、地域等,比如可以按照商品汇总一天的交易额,可以按照卖家汇总一天的营业额(交易额) 可以按照商品与地域汇总一月的交易额。

11.7.2 聚集的基本步骤

第一步:确定聚集维度。
在原始明细模型中会存在多个描述事实的维度 ,如 日期、商品类卖家等,这时候需要确定根据什么维度聚集 ,如果只关心商品的交易额情况,那么就可以根据商品维度聚集数据。
第二步:确定一致性上钻。
这时候要关心是按月汇总还是按天汇总,是按照商品汇总还是按照类目汇总,如果按照类目汇总,还需要关心是按照大类汇总还是小类汇总。当然,我们要做的只是了解用户需要什么,然后按照他们想要的进行聚集。
第三步:确定聚集事实。
在原始明细模型中可能会有多个事实的度量,比如在交易中有交易额、交易数量等,这时候要明确是按照交易额汇总还是按照成交数量汇总。

11.7.3 阿里公共汇总层

1 .基本原则
除了聚集的基本原则外,阿里巴巴建设公共汇总层还必须遵循以下原则。
● 数据公用性。汇总的聚集会有第三者使用吗?基于某个维度的聚集是不是经常用于数据分析中?如果答案是肯定的,那么就有必要把明细数据经过汇总沉淀到聚集表中。
● 不跨数据域。数据域是在较高层次上对数据进行分类聚集的抽象。阿里巴巴以业务过程进行分类,如交易统一划到交易域下,商品的新增、修改放到商品域下。
● 区分统计周期。在表的命名上要能说明数据的统计周期,如_1d表示最近1天,_td 表示截至当天,_nd 表示最近N天。
2. 交易汇总表设计
聚集是指针对原始明细粒度的数据进行汇总。假定已有的交易订单明细模型如图 11.26 所示,可以看出事实和商品、卖家、买家等维度关联

潜在的聚集如表11.8 所示:

可以看出聚集的组合可能性为各个维度属性个数的乘积: 2×2× 2 × …。下面将按照聚集的基本步骤来介绍聚集表的设计流程。
( l )按商品粒度汇总
● 确定聚集维度一一商品。
● 确定一致性上钻一一按商品(商品 ID )最近1天汇总。
● 确定聚集事实一一下单量、交易额。
因此,按商品聚集的星形模型如图11.27 所示。

可以看出聚集的事实都是原始模型中的事实,聚集的维度也是原始模型维度中的商品维度,去掉了其他不关心的维度。
(2 )按卖家粒度汇总
● 确定聚集维度----卖家。
● 确定一致性上钻一 按卖家(卖家 ID )最近7天和最近 30 天汇总。
● 确定聚集事实一一交易额。
因此,按卖家聚集的星形模型如图 1.28 所示。

前面在“聚集的基本原则”中说过,应该避免将不同层级的数据放在一起,为此我们选择用两列存放7天和 30 天的事实,但是需要在列名和字段注释上说清楚。
(3 )按卖家、买家、商品粒度汇总
● 确定聚集维度一一卖家、买家、商品。
● 确定一致性上钻一一按卖家(卖家 ID 、买家(买家 ID )、 商品(商品 ID )最近1天汇总。
● 确定聚集事实一一交易额。
因此,按卖家、买家、商品聚集的星形模型如图 1.29 所示。
可以看出聚集的粒度越细,记录的条数越多,就会越接近原始明细模型的粒度。
(4 )按二级类目汇总
● 确定聚集维度一一类目。
● 确定一致性上钻一一按最近1天类目维度的二级维度属性汇总。
● 确定聚集事实一一交易额。
因此,按二级类目聚集的星形模型如图 1.30 示。

与之前的三个聚集表不同的是,这个聚集模型不是根据维度主键属性进行的聚集,而是根据类目的层次维度属性进行的上钻聚集。

11.7.4 聚集补充说明

1 .聚集是不跨越事实的
聚集是针对原始星形模型进行的汇总,为了获取和查询与原始模型一致的结果,聚集的维度和度量必须与原始模型保持一致,因此聚集是不跨越事实的。横向钻取是针对多个事实基于一致性维度进行的分析,很多时候采用融合事实表,预先存放横向钻取的结果,从而提高查询性能。因此,融合事实表是一种导出模式而不是聚集。
2.聚集带来的问题
聚集会带来查询性能的提升,但聚集也会增加 ETL 维护的难度。当子类目对应的一级类目发生变更时,先前存在的、已经被汇总到聚集表中的数据需要被重新调整。这一额外工作随着业务复杂性的增加,会导致多数 ETL 人员选择简单强力的方法,删除并重新聚集数据。
注:本章节部分理论来自于 Christopher Adamson Star Schema -The Complete Reference Ralph Kimball The Data Warehouse Toolkit-The Definitive Guide to Dimensional Modeling 本书结合阿里的实践进行讲解,细节内容请参考各自著作进行学习

大数据之路读书笔记-11事实表设计相关推荐

  1. 大数据之路读书笔记-10维度设计

    大数据之路读书笔记-10维度设计 文章目录 大数据之路读书笔记-10维度设计 10.1 维度设计基础 10.1.1 维度的基本概念 10.1.2 维度的基本设计方法 10.1.3 维度的层次结构 10 ...

  2. 大数据之路读书笔记-16数据应用

    大数据之路读书笔记-16数据应用 全球知名咨询公司麦肯锡称:"数据,已经 透到当今每一个行业和业务职能领域,成为重要的生产要素.人们对于海量数据的挖掘和运用,预示着新一波生产率增长和消费者盈 ...

  3. 大数据之路读书笔记-01总述

    大数据之路读书笔记-01总述 此系列文章为大数据之路的读书笔记,如侵可删 2014 年,马云提出,"人类正从 IT 时代走向 DT 时代 "如果说IT时代是以自我控制.自我管理为主 ...

  4. 大数据之路读书笔记-03数据同步

    大数据之路读书笔记-03数据同步 如第一章所述,我们将数据采集分为日志采集和数据库数据同步两部分.数据同步技术更通用的含义是不同系统间的数据流转,有多种不同的应用场景.主数据库与备份数据库之间的数据备 ...

  5. 大数据之路读书笔记-15数据质量

    大数据之路读书笔记-15数据质量 随着 IT向DT 时代的转变,数据的重要性不言而喻,数据的应用也日趋繁茂,数据正扮演着一个极其重要的角色.而对于被日益重视的数据,如何保障其质量也是间里巴巴乃至业界都 ...

  6. 大数据之路读书笔记-09阿里巴巴数据整合及管理体系

    大数据之路读书笔记-09阿里巴巴数据整合及管理体系 面对爆炸式增长的数据,如何建设高效的数据模型和体系,对这些数据进行有序和有结构地分类组织和存储,避免重复建设和数据不一致性,保证数据的规范性, 直是 ...

  7. 大数据之路读书笔记-02日志采集

    大数据之路读书笔记-02日志采集 数据采集作为阿里大数据系统体系的第 环尤为重要.因此阿里巴巴建立了一套标准的数据采集体系方案,致力全面.高性能.规范地完成海量数据的采集,并将其传输到大数据平台.本章 ...

  8. 阿里巴巴大数据之路读书笔记——用户画像的定义

    用户画像 在阿里巴巴旗下的淘宝网.虾米音乐上都不乏个性化推荐场景,淘 宝.天猫平台上的众多商家则需要通过用户调研和产品研发来把握产品 的目标人群和人群偏好,从而对用户投其所好.对用户有深刻的理解是 网 ...

  9. 阿里巴巴大数据之路读书分享

    阿里巴巴大数据之路读书分享 文章目录 阿里巴巴大数据之路读书分享 前言 阿里巴巴大数据系统的体系架构图及介绍 数据采集层 数据采集 数据传输 数据计算层 离线数据开发 实时数据开发 数据服务层 数据应 ...

最新文章

  1. 客户花钱雇黑客,竟是为Zoom找bug:风口浪尖的视频会议No.1,安全问题如此魔幻...
  2. 遍历 HashSet 的方法
  3. 弱网优化在支付宝的深度实践 | mPaaS 线下沙龙 CodeDay#1 分享实录
  4. android异步更新UI
  5. 龙图 VP 李翀:数据化运营及云计算下的运维
  6. 基于脚手架创建react项目
  7. 安装mysql5.6.10_windows下安装mysql(mysql-installer-community-5.6.10.1)详细教程
  8. Android之IPC机制
  9. ftp网页服务器不允许匿名登录,我的FTP服务器不让匿名登陆,怎么办?
  10. python卸载干净_Python卸载不干净?Mac完全卸载python方法
  11. leetcode Largest Rectangle in Histogram 单调栈
  12. 微信小程序发送模板消息通知
  13. 例3.6 二叉搜索树 - 九度教程第36题(二叉排序树)
  14. jQuery-可收缩面板
  15. 【机器人学:运动规划】快速搜索随机树(RRT---Rapidly-exploring Random Trees)入门及在Matlab中演示
  16. 你以为你了解Kaggle吗?| 超级干货
  17. oppo小布机器人_OPPO小布助手喜迎重大升级,你的私人全能管家现已上线!
  18. 浏览器内核和Standards模式与Quirks模式
  19. ​力扣解法汇总606-根据二叉树创建字符串
  20. 网站统计中的数据收集原理及实现

热门文章

  1. idea 好用的插件和快捷键
  2. 基于Hackrf的GNSS接收机
  3. The elements of programming style,好程序的要素
  4. Think Different
  5. 频率学派和贝叶斯学派的参数估计
  6. adb 常用命令记录
  7. python startswith_Python startswith()方法 - Python 教程 - 自强学堂
  8. Excel单元格下拉框引用其它Sheet中的值的方法
  9. markdown工作随笔总结
  10. Dropbear 安装配置与启动ssh服务详解