【阿里巴巴大数据之路】事实表设计

事实表基础

事实表特性

事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度和与业务过程有关的度量。

作为业务过程的事实,一般为整型或浮点型的十进制数值,有可加性、半可加性和不可加性三种类型。

  • 可加性事实是指可以按照与事实表关联的任务维度进行汇总。
  • 半可加性事实只能按照特定维度汇总,不能对所有维度汇总,比如库存可以按照地点和商品进行汇总,而按时间维度把一年中每个月的库存累加起来则毫无意义。
  • 还有一种度量完全不具备可加性,比如比率型事实。

维度属性也可以存储到事实表中,这种存储到事实表中的维度列被称为"退化维度"。与其他存储在维表中的维度一样,退化维度也可以用来进行事实表的过滤查询、实现聚合操作等。

事实表有三种类型:

  • 事务事实表:用来描述业务过程,跟踪空间或时间上某点的度量时间,保存的是最原子的数据,也称为"原子事实表"。
  • 周期快照表:以具有规律性的、可预见的时间间隔记录事实,时间间隔如每天、每月、每年等。
  • 累积快照事实表:用来表述过程开始和结束之间的关键步骤时间,覆盖过程的整个生命周期,通常具有多个日期字段来记录关键时间点,当过程随着生命周期不断变化时,记录也会随着过程的变化而被修改。

事实表设计原则

  • 原则1:尽可能包含所有与业务过程相关的事实
    事实表设计的目的是为了度量业务过程,所以分析哪些事实与业务过程有关是设计中非常重要的关注点。
  • 原则2:只选择与业务过程相关的事实
    如在订单的下单这个业务过程的事实表设计中,不应该存在支付金额这个表示支付业务过程的事实表。
  • 原则3:分解不可加和性事实为可加的组件
    对于不具备可加性条件的事实,需要分解为可加的组件。比如比率型分解为分子和分母。
  • 原则4:在选择维度和事实之前必须先声明粒度
    粒度用于确定事实表中一行所表示业务的细节层次,决定了维度模型的扩展性。在事实表中,通常通过业务描述来表述粒度。但对于聚集性事实表的粒度描述,可采用维度或维度属性组合的方式。
  • 原则5:在同一个事实表中不能有多种不同粒度的事实
    事实表中的所有事实需要与表定义的粒度保持一致,在同一个事实表中不能有多种不同粒度的事实。
  • 原则6:事实的单位要保持一致
    对于同一个事实表中事实的单位,应该保持一致。
  • 原则7:对事实的null值要处理
    因为在数据库中,null值对常用数字型字段的sql过滤条件都不生效,比如大于、小于无法过滤空值。
  • 原则8:使用退化维度提高事实表的易用性
    目的是减少下游用户使用时关联多个表的操作,直接通过退化维度实现对事实表的过滤查询、控制聚合层次、排序数据以及定义主从关系等。通过增加冗余存储的方式减少计算开销、提高使用效率。

事实表设计方法

对于维度模型设计采用四步设计法:选择业务过程、声明粒度、确定维度、确定事实。目前的改进是,增加一步:冗余维度(使用退化维度)。

  • 选择业务过程及确定事实表类型:业务过程通常使用行为动词表示业务执行的活动,如创建订单、买家付款等。如果事实表只需要包含一个业务过程,则为单实务事实表。如果包含所有业务过程且需要分析各个业务过程之间的时间间隔,那么建立的为累积快照事实表。
  • 声明粒度:精确定义事实表的每一行所表示的业务含义。应该尽量选择最细级别的原子粒度,以确保事实表的应用具有最大的灵活性。
  • 确定维度:应该选择能够描述清楚业务过程所处的环境的维度信息。
  • 确定事实:事实可以通过回答"过程的度量是什么"来确定。应该选择与业务过程有关的所有事实,且事实的粒度要与所声明的事实表粒度一致。
  • 冗余维度。

事务事实表

以淘宝交易订单中关于邮费和折扣分摊到子订单的算法为例,介绍三种不同事务事实表的设计方法。

设计过程

任何类型的事件都可以被理解为一种事务。例如交易过程中的创建订单、买家付款,物流过程中的揽货、发货、签收,退款过程中的申请退款、申请小二介入等,都可以被理解为一种事务。事务事实表,即针对这些过程构建的一类事实表,用以跟踪定义业务过程的个体行为,提供丰富的分析能力,作为数据仓库原子的明细数据。

  1. 选择业务过程

买家下单 创建订单 等待卖家付款 买家付款 等待卖家发货 卖家发货 等待买家确认收货 买家确认收货 交易成功

上述订单流转过程中存在四个重要的过程:创建订单、买家付款、卖家发货、买家确认收货,即下单、支付、发货和成功完结四个业务过程。这四个业务过程不仅是交易过程中的重要时间节点,而且也是下游统计分析的重点,因此,淘宝交易事务事实表设计着重从这四个业务过程进行展开。

  1. 确定粒度
    淘宝交易的业务逻辑:淘宝下单交易时,有两种方式:一种是选定商品后直接购买,这样会产生一个交易订单。一种是加入购物车后合并购买,此时对于每一种商品都会产生一个订单,而对于同一个店铺会额外产生一个订单,此称为父订单,由于是同一个订单买的,所以父订单会承载订单物流、店铺优惠等信息。而对于每个商品产生的订单,称为子订单,子订单记录了父订单的订单号,并且有子订单标志。如果在同一个店铺只购买了一种商品,则会将父子订单进行合并,只保留一条订单记录。
    业务过程选定之后,就要针对每个业务过程确定一个粒度,即确定事务事实表每一行所表达的细节层次。上述四个业务过程中,下单、支付、成功完结三个业务过程选择交易子订单粒度,即每个子订单为事务事实表的一行,每个子订单所表达的细节信息为交易时间、卖家、买家、商品。由于同一个子订单可以拆开成多个物流单进行发货,所以卖家发货这个业务过程确定为物流单粒度,和其他三个业务过程不同。
  2. 确定维度
    按照经常用于统计分析的场景,确定维度包含:买家、卖家、商品、商品类目、发货地区、收货地区、父订单维度以及杂项维度。由于订单的属性较多,比如订单的业务类型、是否无线交易、订单的attributes属性等,对于这些使用较多却又无法归属到上述买卖家或商家维度中的属性,则新建一个杂项维度进行存放。
  3. 确定事实
    作为过程度量的核心,事实表应该包含与其描述过程有关的所有 事实,不同的业务过程有不同的事实。由于粒度是子订单,所以对于一些父订单上的金额需要分摊到子订单上,比如父订单邮费、父订单折扣等。该如何分摊?
  4. 冗余维度
    将买卖家星级、标签、店铺名称、商品类型等维度属性都冗余到事实表中,提高对事实表进行过滤查询、统计聚合的效率。
    上述过程同时存在[退化维度]的步骤:将常用维度全部退化到事实表中,使得下游分析使用模型更加方便。
    对于上述设计过程存在一个问题:单一事实表中是否包含多个业务过程?

单事务事实表

即针对每个业务过程设计一个事实表。优点:可以方便地对每个业务过程进行独立的分析。由于事实表具有稀疏性质,因此只有当天数据才会进入当天的事实表中。

多事务事实表

多事务事实表,将不同的事实放到同一个事实表中,即同一个事实表包含不同的业务过程。多事务事实表在设计时有两种方法进行事实的处理:一种是不同业务过程的事实使用不同的事实字段进行存放,此方法的问题是零值较多;一种是不同业务过程的事实采用同一个事实字段存放,但增加一个业务过程标签,此方法的问题是同一周期会存在多条记录。当不同业务度量差异不大时,用后者,否则用前者。

单事务事实表和多事务事实表的区别

  1. 业务过程:如果不同业务过程之间相似性和业务源系统一致,则采用多事务事实表(如交易的下单、支付、成功完结)。
  2. 粒度和维度:当不同业务过程的粒度相同,同时拥有相似的维度时,此时可以考虑多事务事实表。
  3. 事实:对于不同的业务过程,事实往往是不同的。如果单一业务过程的事实比较多,同时不同业务过程的事实又不相同,则可以考虑使用单事务事实表,处理更加清晰。
  4. 计算存储成本:当业务过程数据来源于同一个业务系统,具有相同的粒度和维度,且维度较多而事实相对不多时,此时可以考虑使用多事务事实表,降低加工计算成本和存储成本。

父子事实的处理方式

例如:子订单分摊的支付金额=父订单支付金额✖支付分摊比例。

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

事实表的设计准则

  1. 事实完整性:事实表包含与其描述的过程有关的所有事实,即尽可能多地获取所有的度量。
  2. 事实一致性:在确定事务事实表的事实时,明确存储每一个事实以确保度量的一致性。
  3. 事实可加性:可能会遇到非可加性变量,如分摊比例、利润率等,但更多的是可加变量。

周期快照事实表

事务事实表可以很好地跟踪一个事件,并对其进行度量,以提供丰富的分析能力。然而,当需要一些状态变量时,比如账户余额等,则需要聚集与之相关的事务才能进行识别计算;或者聚集事务无法识别。对于这些状态变量,事务事实表是无效率的,而这些度量也和度量事务本身一样是有用的,因此,维度建模理论给出了第二种常见的事实表-周期快照事实表,简称"快照事实表"。

快照事实表在确定的间隔内对实体的度量进行抽样,这样可以很容易地研究实体的度量值,而不需要聚焦长期的事务历史。

特性

事务事实表的粒度能力多种方式表达,但快照事实表的粒度通常以维度形式声明。事务事实表是稀疏的,其中的事实是完全可加的,而快照事实表是稠密的,将至少包含一个用来展示半可加性质的事实。

  1. 用快照采样状态:快照事实表以预定的间隔采样状态度量。这种间隔联合一个或多个维度,将被用来定义快照事实表的粒度,每行将包含记录所涉及状态的事实。(如自然年初截至昨日)
  2. 快照粒度:事务事实表的粒度可以通过业务过程中涉及的细节程度来描述,但快照事实表的粒度通常总是被多维声明,可以简单地理解为快照需要采样的周期以及什么将被采样。
  3. 密度与稀疏性:无论当天是否有业务过程发生,都会记录一行。
  4. 半可加性:每个采样周期内不能对状态度量进行汇总。

其设计步骤可以归纳为:

  • 确定快照事实表的快照粒度
  • 确定快照事实表采样的状态度量

分类:

  • 单维度的每天快照事实表:采样周期为每天,针对单独的卖家、买家等维度的快照事实表。
  • 混合维度的每天快照事实表:混合维度相对于单维度,只是针对多个维度进行采样。如卖家加买家。

上述两类快照事实表都可以从事务事实表进行汇总产出-这是周期快照事实表一种常见的产出模式。

另一种产出模式是-直接使用操作型系统的数据作为周期快照事实表的数据源进行加工,比如卖家星级事实表等。

  • 这类由于卖家信用分是在操作型系统中计算完成的,所以直接采用操作型系统数据进行设计加工,采样周期是每天,针对卖家维度统计,状态度量就是卖家信用分。
  • 全量快照事实表:如淘宝好中差评快照事实表。每天按照评价进行采样,每一条好中差评就是表的最细粒度。由于对于好中差评价的度量关注更多的是评价本身,没有类似于金额、商品数这样的度量,因此设计为无事实的事实表,更多地关注评价的状态。同时,冗余了维度。
注意事项
  • 事务与快照成对设计:数据仓库维度建模时,对于事务事实表和快照事实表往往都是成对设计的,互相补充,以满足更多的下游统计分析需求,特别是在事务事实表的基础上可以加工快照事实表。既丰富了星型模型,又降低了下游分析的成本。
  • 附加事实:快照事实表在确定状态度量时,一般都是保存采样周期结束时的状态度量。有时会附加一些上一个采样周期的状态度量。
  • 周期到日期度量:在确定周期快照事实表的度量时,也要考虑自然年至今、极度至今、财年至今类似的度量值,可以针对多种周期到日期的度量设计不同的快照事实表。

累积快照事实表

累积快照事实表就是:针对一个有明确生命周期的业务过程(Process),在同一行记录中反映该过程从开始到结束的关键阶段时间与指标。对于类似于研究事件之间时间间隔的需求,采用累积快照事实表可以很好地解决。

设计过程

对于累积快照事实表,其建模过程和事务事实表相同,适用于维度建模的步骤。

  1. 选择业务过程。以淘宝交易订单流转为例,统计时间时间间隔的需求中,卖家发货也是关键环节。所以同样考虑买家下单、买家支付、卖家发货、买家确认收货四个业务过程。
  2. 确定粒度:对于累积快照事实表,用于考察实体的唯一实例,所以子订单在此表中只有一行记录,事件发生时,对此实例进行更新。(事务事实表是每个事件都会记录一行)。
  3. 确定维度:与事务事实表相同,维度主要有买家、卖家、店铺、商品等。四个业务过程对应的时间字段,格式为日期+时间,分别为下单时间、支付时间、发货时间、确认收货时间,对应于日期维表。
    在交易订单表中,存在很多与订单相关的属性,如订单类型、子类型、支付状态等,类似的属性字段,无法归属到已有的商品维度,所以新建杂项维度存放。在数据仓库建模理论中,杂项维度无自然键,一般是枚举值的组合,对于每个组合生成一个代理键。但在实际建模中,存在很多非枚举值,且对于每个订单都不相同。所以实际中杂项维度设计时,也可以直接使用自然键标识具体的维度值。如拆成父订单维度和子订单维度。
  4. 确定事实:对于累积快照事实表,需要将各业务过程对应的事实均放入事实表中。累积快照事实表解决的最重要的问题是统计不同业务过程之间的时间间隔,建议将每个过程的时间间隔作为事实放在事实表中。而如果每个过程时间间隔计算逻辑简单,也可以直接把原子指标(关键时间点)放入事实表中。
  5. 退化维度:在大数据时代,很多维表比事实表还大,在分布式数据仓库系统中,事实表和维表关联的成本很高。所以在传统的维度模型设计完成之后,在物理实现中将各维度的常用属性退化到事实表中,以大大提高对事实表的过滤查询、统计聚合等操作的效率。
特点
  1. 数据不断更新:事务事实表记录事务发生时的状态,对于实体的某一实例不再更新;累积快照事实表则对实体的某一实例定期更新。如一个订单下单、支付、确认收货在事务事实表中有三行记录,在累积快照事实表中只会对一行记录反复更新。
  2. 多业务过程日期:累积快照事实表适用于具有较明确起止时间的短生命周期实体,如交易订单、物流订单等,对于实体的每一个实例,都会经历从诞生到消亡等一系列步骤。对于商品、用户等具有长生命周期的实体,一般采用周期快照事实表更合适。
    其典型特征是多业务过程日期,用于计算业务过程之间的时间间隔。
  3. 还有一个重要的作用是保存全量数据。如果要保留历史截至当前的所有交易数据,其中一种方式是在ODS层保留和源系统结构完全相同的数据;但由于使用时需要关联维度,较为麻烦,所以在公共明细层需要保留一份全量数据。可用交易累积快照事实表存放加工后的事实,并将各维度常用属性和订单杂项维度退化到此表中。
特殊处理
  1. 非线性过程:并非所有订单都会走完下单->支付->发货->确认收货四个业务过程,也有交易会在申请退款->驳回退款->申请退款里循环流程。针对非线性过程,处理情况主要有以下几种:
    • 业务过程的统一。如可以以交易结束作为流程结束、实体消亡的标志,包括交易完成和交易结束两种情况。
    • 针对业务关键里程碑构建全面的流程。对于没有支付或发货的订单,全流程仍然可以覆盖,相关业务过程的时间字段和事实置空。
    • 循环流程的处理:主要问题是解决一个业务过程存在多个里程碑日期的问题。使用业务过程第一次发生的日期还是最后一次发生的日期,由也业务方决定。
  2. 多源过程:针对多业务过程建模时,业务过程可能来自于不同系统或者来源于不同的表,其对模型设计没有影响,但会涉及交易、售后、物流三个业务源系统。
    针对多源业务建模,主要考虑事实表的粒度问题。如对于退款,如果要将退款相关业务过程加入模型中,则需要和商业用户确定存在多次退款时如何取舍,确保模型粒度不变。
  3. 业务过程取舍:当拥有大量的业务过程时,模型的实现复杂度会增加,特别是对于多源业务,模型的耦合度过高,此时需根据商业用户需求,选取关键的里程碑(剪枝)。
物理实现
  • 可以用全量表的形式实现,每天的分区存储昨天的全量数据和当天的增量数据合并的结果,保证每条记录的状态更新。此方法适合全量数据较少的情况。
  • 可以用全量表的变化形式。针对事实表数据量很大的情况,确定一个相对较大的时间间隔,对于时间间隔外的数据建分区存储在归档表中。存储消耗较大。
  • 以业务实体的结束时间分区,每天的分区存放当天结束的数据,设置一个时间非常大的分区,存放截至当前未结束的数据。由于每天将当天结束的数据归档值当天分区中,时间非常大的分区数据量不会很大,ETL性能较好,且无存储的浪费。

如果以业务实体的结束时间分区,有时无法判断业务实体是否已经消亡,如菜鸟的物流订单,针对此问题,可以有两种解决方式:

  1. 使用相关业务系统的业务实体的结束标志作为此业务系统的结束标志。如物流订单可以用交易订单的结束作为结束标志。
  2. 和前端业务系统确定口径或使用前端归档策略。和前端业务系统确定口径,确定从业务实体的产生到消亡的最大时间间隔。也可以使用前端归档时间作为业务实体的结束日期。

三种事实表的比较

事务事实表 周期快照事实表 累积快照事实表
时间/时期 离散事务时间点 以有规律的、可预测的间隔产生快照 用于时间跨度不确定的不断变化的工作流
日期维度 事务日期 快照日期 相关业务过程涉及的多个日期
粒度 每行代表实体的一个事务 每行代表某时间周期的一个实体 每行代表一个实体的生命周期
事实 事务事实 累积事实 相关业务过程事实和时间间隔事实
事实表加载 插入 插入 插入与更新
事实表更新 不更新 不更新 业务过程变更时更新

无事实的事实表

不包含事实或度量的事实表称为"无事实的事实表",虽然没有明确的事实,但可以用来支持业务过程的度量。有如下两种:

  • 事件类:记录时间的发生,如日志类事实表。
  • 条件、范围或资格类的,记录维度与维度多对多之间的关系。

聚集型事实表

聚集主要是通过汇总明细粒度数据来获得改进查询性能的效果。通过访问聚集的数据,可以减少数据库在响应查询时必须执行的工作量,能够快速响应用户的查询,同时有利于减少不同用户访问明细数据带来的结果不一致问题。

尽管聚集能带来良好的收益,但需要事先对其进行加载和维护,这将会对给ETL带来更多的挑战。将使用频繁的公用数据,通过聚集进行沉淀,比如卖家最近1天的交易汇总表,这类聚集汇总数据,被叫做"公共汇总层"。

聚集的基本原则
  • 一致性。聚集表必须提供与查询明细粒度数据一致的查询结果。从设计角度来看,确保一致性,最简单的方法是确保聚集星型模型中的维度和度量与原始模型中的维度和度量保持一致。
  • 避免单一表设计。不要在同一个表中存储不同层次的聚集数据。可以将按天汇总和按月汇总的数据用两列存储,需要在列名或列注释上能分辨出来。
  • 聚集粒度可不同。聚集并不需要保持与原始明细粒度数据一样的粒度,只关心所需要查询的维度。
聚集的基本步骤
  • 确定聚集维度
  • 确定一致性上钻:关心是按月汇总还是按天汇总,按商品汇总还是按类目汇总。要做的只是了解用户需要什么,然后按照他们想要的进行聚集。
  • 确定聚集事实:明确按照交易额汇总还是按照成交数量汇总。
阿里公共汇总层

基本原则:

  • 数据公用性:如果经常用于数据分析中,则必要把明细数据经过汇总沉淀到聚集表中。
  • 不跨数据域。数据域是在较高层次上对数据进行分类聚集的抽象。阿里巴巴以业务过程进行分类,如交易统一划分到交易域下,商品的新增、修改放到商品域下。
  • 区分统计周期。在表的命名上要能说明数据的统计周期。
聚集补充说明
  • 不跨越事实:聚集是针对原始星型模型进行的汇总。为了保证一致,聚集的维度和度量必须与原始模型保持一致,因此聚集是不跨越事实的。横向钻取是针对多个事实基于一致性维度进行的分析,很多时候采用融合事实表,预先存放横向钻取的结果,从而提高查询性能。融合事实表示一种导出模式而不是聚集。
  • 聚集带来的问题:聚集会带来查询性能的提升,也会增加ETL维护的难度。当子类目对应的一级类目发生变更时,先前存在的、已经被汇总到聚集表中的数据需要被重新调整。
相关推荐
我星期八休息5 小时前
C++智能指针全面解析:原理、使用场景与最佳实践
java·大数据·开发语言·jvm·c++·人工智能·python
wudl55667 小时前
flink sql 所有函数详细用例
大数据·sql·flink
luoganttcc8 小时前
是凯恩斯主义主导 西方的经济决策吗
大数据·人工智能·金融·哲学
武子康8 小时前
大数据-130 - Flink CEP 详解 - 捕获超时事件提取全解析:从原理到完整实战代码教程 恶意登录案例实现
大数据·后端·flink
分布式存储与RustFS8 小时前
存算一体架构的先行者:RustFS在异构计算环境下的探索与实践
大数据·人工智能·物联网·云原生·对象存储·minio·rustfs
wudl556613 小时前
Flink 1.20 flink-config.yml 配置详解
大数据·flink
华东数交13 小时前
企业与国有数据资产:入表全流程管理及资产化闭环理论解析
大数据·人工智能
B站_计算机毕业设计之家19 小时前
计算机毕业设计:Python农业数据可视化分析系统 气象数据 农业生产 粮食数据 播种数据 爬虫 Django框架 天气数据 降水量(源码+文档)✅
大数据·爬虫·python·机器学习·信息可视化·课程设计·农业
Apache Flink21 小时前
Flink Agents 0.1.0 发布公告
大数据·flink