概述
上一篇主要阐述了维度表的设计,而本篇主要阐述怎么创建事实表。维度表是围绕业务过程所处环境设计,那么事实表则是围绕业务过程设计;而接下来将深入阐述事实表模型设计。例如:事实表有几种类型、什么是可加、半可加和不可加;后续内容将展开说明。
What(什么是事实表)
事实表是指对实体发生行为事实时所产生的数据组合成的模型。事实表是不断动态增长,数据量一般比维度表要大;例如商品交易表、系统日志表等等属于事实表。事实表的组成包括与该业务过程相关的维度引用(维度表的外键),以及该业务过程的度量(可累加的数字字段,例如:金额)。
Why(为什么创建事实表)
数仓的核心是赋能业务(可以使业务更快看到各项指标,以及提供数据挖掘的基础),那么事实表就表示每一个业务下的一条流程;因此事实表作为搭建数仓的根基,事实表设计的好坏直接决定了数仓的质量。
How(怎么创建事实表)
事实表有三种类型:事务事实表、周期快照事实表和累计快照事实表,接下来将详细介绍。
事务事实表
事务事实表用来记录各业务过程,它保存的是各业务过程的原子操作事件,即最细粒度的操作事件。粒度是指事实表中一行数据所表达的业务细节程度(例如:订单商品表就表示为最小粒度)。事务型事实表可用于分析与各业务过程相关的各项统计指标,由于其保存了最细粒度的记录,可以提供最大限度的灵活性,可以支持无法预期的各种细节层次的统计需求。
设计流程
事务事实表一般可遵循以下四个步骤:选择业务过程 → 声明粒度 → 确认维度 → 确认事实
选择业务过程:
详细分析业务需求,梳理涉及到的每一个业务过程,业务过程可以概括为一个个不可拆分的行为事件,例如电商交易中的下单,取消订单,付款,退单等,都是业务过程。通常情况下,一个业务过程对应一张事务型事实表。声明粒度:
业务过程确定后,需要为每个业务过程声明粒度。即精确定义每张事务型事实表的每行数据表示什么,应该尽可能选择最细粒度,以此来应各种细节程度的需求。典型的粒度声明如下:订单事实表中一行数据表示的是一个订单中的一个商品项。确认维度:
确定维度具体是指,确定与每张事务型事实表相关的维度有哪些。确定维度时应尽量多的选择与业务过程相关的环境信息。因为维度的丰富程度就决定了维度模型能够支持的指标丰富程度。确认事实:
此处的“事实”一词,指的是每个业务过程的度量值(通常是可累加的数字类型的值,例如:次数、个数、件数、金额等)。冗余维度:
在设计事实表模型时,需要更多的考虑是提高下游用户的使用效率,降低数据获取的复杂性,减少关联的表数量。所以通常事实表中会冗余方便下游用户使用的常用维度,以实现对事实表的过滤查询、控制聚合层次、排序数据以及定义主从关系等操作。
经过上述五个步骤,事务型事实表就基本设计完成了。第一步选择业务过程可以确定有哪些事务型事实表;第二步可以确定每张事务型事实表的每行数据是什么;第三步可以确定每张事务型事实表的维度外键;第四步可以确定每张事务型事实表的度量值字段;第五步冗余部分(指的是可以降低数据获取的复杂性,减少关联的表数量的维度字段)维度数据到事实表中。
事实的设计准则
事实完整性:
事实表包含与其描述的过程有关的所有事实,即尽可能多地获取所有的度量。事实一致性:
在确定事务事实表的事实时,明确存储每一个事实以确保度量的一致性。事实可加性:
事实表确定事实时,遇到非可加性度量,比如分摊比例、利润率等,虽然它们也是下游分析的关键点,但往往在事务事实表中关注更多的是可加性事实,下游用户在聚合统计时更加方便。
事务事实表不足之处
事务事实表中保存了所有业务过程的最细粒度,基本上可以支撑各个业务过程相关的各种统计指标的需求;但是对于某些需求,其实现的逻辑可能会比较复杂或者效率比较低。例如:
存量型指标:
商品库存之类的,如果有需求需要获取当前的商品库存是多少,按照事务事实表的设计原则是将商品库存每日的流水进去全部聚合;随着该表数据量的越来越大,其实现的效率就会越来越差。多事务关联统计:
指的是某些指标需要通过多个事务事实表进行关联统计,才可以实现的指标;处理逻辑上不复杂,但事务事实表的数据量是比较大的,那么多张事务事实表进行 Join 其效率肯定较低。
周期快照事实表
周期快照事实表以具有规律性的、可预见的时间间隔来记录事实,主要用于分析一些存量型(例如商品库存,账户余额)或者状态型(空气温度,行驶速度)指标。
存量型指标:
对于商品库存、账户余额这些存量型指标,业务系统中通常就会计算并保存最新结果,所以定期同步一份全量数据到数据仓库,构建周期型快照事实表,就能轻松应对此类统计需求,而无需再对事务型事实表中大量的历史记录进行聚合了。状态型指标:
对于空气温度、行驶速度这些状态型指标,由于它们的值往往是连续的,我们无法捕获其变动的原子事务操作,所以无法使用事务型事实表统计此类需求。而只能定期对其进行采样,构建周期型快照事实表。
设计流程
周期快照表一般可遵循以下二个步骤:确定粒度 → 确认事实
确定粒度:
周期型快照事实表的粒度可由采样周期和维度描述,确定采样周期和维度后即可确定粒度。采样周期通常选择每日。维度可根据统计指标决定,例如指标为统计每个仓库中每种商品的库存,则可确定维度为仓库和商品。确定完采样周期和维度后,即可确定该表粒度为每日-仓库-商品。确认事实:
事实也可根据统计指标决定,例如指标为统计每个仓库中每种商品的库存,则事实为商品库存。
事实类型
事实表中度量一般为整数或浮点型数值,有三种类型:可加性、半可加性和不可加性。说明如下:
可加性:
指的是可以按照与事实表关联的任意维度进行汇总,例如:订单金额就是典型的可加性,所有的维度都可以进行统计。半可加性:
只能按照特点维度进行汇总,不能对所有维度进行汇总;例如:库存可以按照地点和商品进行汇总,但按照时间维度把一年中每一个月汇总起来则毫无意义。不可加性:
指的是不具备可加性,汇总后没有任何意义;例如:比率型事实。
累积快照事实表
累积快照事实表是基于一个业务流程中的多个关键业务过程联合处理而构建的事实表,如交易流程中的下单、支付、发货、确认收货业务过程。因此累积型快照表通常会有多个日期字段,每个日期对应一个业务流程中的关键业务过程。例如:某个指标需要知道用户下单到支付的平均时间间隔,使用累积型快照事实表进行统计,就能避免两个事务事实表的关联操作,从而变得十分简单高效。
设计流程
累积型快照事实表一般可遵循以下四个步骤:选择业务过程 → 声明粒度 → 确认维度 → 确认事实
选择业务过程:
选择一个业务流程中需要关联分析的多个关键业务过程,多个业务过程对应一张累积型快照事实表。声明粒度:
精确定义每行数据表示的是什么,尽量选择最小粒度。确认维度:
选择与各业务过程相关的维度,需要注意的是,每各业务过程均需要一个日期维度。确认事实:
选择各业务过程的度量值。
三种事实表的比较
上面已经对三种事实表展开进行了说明,接下来对这三种事实表比较。如下:
事务事实表 | 周期快照事实表 | 累积快照事实表 | |
---|---|---|---|
时期/时间 | 离散事务时间点 | 以有规律、可预测的时间间隔产生数据 | 用于时间跨度不确定的不断变化的工作流 |
日期维度 | 事务日期 | 快照日期 | 相关业务过程涉及的多个日期 |
粒度 | 每行代表实体的一个事务 | 每行代表某时间周期的一个实体 | 每行代表一个实体的生命周期 |
事实 | 事务事实 | 累积事实 | 相关业务过程事实和时间间隔事实 |
事实表加载方式 | 插入 | 插入 | 插入与更新 |
事实表更新方式 | 不更新 | 不更新 | 业务过程变更时更新 |
事务事实表:
事务事实表记录的是事务层面的事实,用于跟踪业务过程的行为;保存的是最原子的数据(原子事实表),事务事实表的数据是在事务发生后产生的,而数据的粒度就是每个事务的一行数据;当事务被提交的及事实表数据插入,数据就不能进行更改(更新的方式就为增量更新)。周期快照事实表:
周期快照事实表是以具有规律性的、可预见性时间间隔来记录事实(比如:账户余额、库存、层级等等),时间间隔一般为每天、每月等等;周期快照事实表的日期维度通常记录时间段的终止日,记录的事实是这个时间段内一些聚集事实值或状态度量;事实表的数据一旦插入就不能更改(更新的方式就为增量更新)。累积快照事实表:
累积快照事实表被用来跟踪实体的一系列业务过程的进展情况,它通常具有多个日期字段,主要用于研究业务过程中的时间间隔;而且这类事实表在数据加载完成后,可以对其数据进行更新,来补充业务状态变更时的日期信息和事实。
事实表大部分都是设计为事务事实表,而其他两种类型表主要取决于实际需求;如何快速、高效的满足需求,以及方便后期可扩展性的表,就设计什么样的表;例如周期快照表与事务事实表是可以同时存在的,二者并不冲突; 假如某个需求需要当前商品库存数量,该需求肯定通过周期快照表来获取更好;如果另一个需求需要最近商品库存明细,该需求通过事务事实表查询则更好。
事实表设计原则
- 原则一:尽可能包含所有与业务过程相关的事实,设计事实表的目的是了度量业务过程,所以事实表中要尽量包含所有与业务过程相关的事实;及时会存在数据的冗余问题(事实通常是数字类型,存储空间不会很大)。
- 原则二:只选择也业务相关的事实,例如在订单的下单这个业务过程的事实表设计时,不应该存在支付金额这个表示支付业务过程的事实。
- 原则三:分解不可加事实为可加组件,将不具备可加性的事实分解为可加的组件;例如订单的成单率,应该分解为成单数和提单数两个事实存储在事实表中。
- 原则四:在选择维度和事实之前必须先申明粒度,粒度是表示事实表中每行所代表的业务层次,决定了维度模型的扩展性;因此在设计事实表时粒度定义的越细越好,这样可以保证最大限度的灵活性(从最低粒度开始设计);同时可以通过业务描述或者维度属性组合的方式来定义粒度。
- 原则五:同一个事实表中不能有多个不同粒度的事实,一个事实表中只能包含同级粒度的度量,不能包含多级粒度的度量。
- 原则六:事实的单位要一致,对于同一个事实表中的事实单位要保持一致;例如订单金额、订单优惠金额、订单运费金额等三种事实应该采用一致的计量单位(元/分)。
- 原则七:事实的 null 值要处理,对于事实表中事实度量为 Null 值的处理,对常用数字型字段的 SQL 过滤处理不生效(比如:大于、小于、等于等等对 Null 值无效),因此最好是用数值代替 Null 值(比如:平均值、0等等)。
- 原则八:使用退化维度提高事实表的易用性,这样有利于减少下游用户使用时关联多个表的操作;直接通过退化维度实现对事实表的过滤查询、控制聚合层次、排序数据以及定义主从关系。通过增加数据的冗余来减少计算开销,从而提高使用效率。
以上示例与内容仅是个人观点,如有误十分感谢提出;内容还在完善中!!!
参考链接:
《大数据之路:阿里巴巴大数据实践》