数仓建模之累计快照事实表设计案例
累计快照事实表的概念
累积快照事实表用来表述过程开始和结束之间的关键步骤事件,覆盖过程的整个生命周期,通常具有多个日期字段来记录关键时间点, 当过程随着生命周期不断变化时,记录也会随着过程的变化而被修改。
设计过程
对于累积快照事实表,其建模过程和事务事实表相同,适用于维度建模的步骤。
下面详述淘宝交易累积快照事实表的设计过程,并讨论和事务事实表的设计差异。
选择业务过程
对于以下四个业务过程,在事务统计中只关注下单、支付和确认收货三个业务过程;而在统计事件时间间隔的需求中,卖家发货也是关键环节。所以针对淘宝交易累积快照事实表,我们选择这四个业务过程。
确定粒度
在“事务事实表”中提到,对于淘宝交易,业务需求一般是从子订单粒度进行统计分析,所以选择子订单粒度。淘宝交易事务事实表的粒度也是子订单,但通常对于子订单的每个事件都会记录一行,对于多事件事实表,如果子订单同一周期发生多次事件则记录一行;而对于累积快照事实表,用于考察实体的唯一实例,所以子订单在此表中只有一行记录,事件发生时,对此实例进行更新。
确定维度
与事务事实表相同,维度主要有买家、卖家、店铺、商品、类目、发货地区、收货地区等。四个业务过程对应的时间字段,格式为日期+时间,分别为下单时间、支付时间、发货时间、确认收货时间,对应于日期维表,图l 1.24 中未标识。在实际使用时会使用视图或SQL 别名的方式表示四个日期角色维度,类似于发货地区维度和收货地区维度。
在交易订单表中,存在很多与订单相关的属性,如订单类型、子类型、支付状态、物流状态、attributes 、options 等。对于类似的属性字段,无法归属到已有的商品等维度中,所以新建杂项维度存放。
在数据仓库建模理论中,杂项维度无自然键,一般是枚举值的组合,对于每个组合生成一个代理键。但在实际建模中,存在很多非枚举值,且对于每个订单都不相同,如订单的attributes 和options 属性。所以实际中杂项维度设计时,也可以直接使用自然键标识具体的维度值,如下:
确认事实
对于累积快照事实表,需要将各业务过程对应的事实均放人事实表中。
比如淘宝交易累积快照事实表,包含了各业务过程对应的事实,如下单对应的下单金额,支付对应的折扣、邮费和支付金额,确认收货对应的金额等。累积快照事实表解决的最重要的问题是统计不同业务过程之间的时间间隔,建议将每个过程的时间间隔作为事实放在事实表中。在淘宝交易累积快照事实表建模中,由于每个过程的时间间隔计算逻辑简单,因此并未加人事实表中,如下:
退化维度
在大数据的事实表模型设计中,更多的是考虑提高下游用户的使用效率,降低数据获取的复杂性,减少关联的表数量。一方面,存储成本降低了,而相比之下CPU 成本仍然较高;另一方面,在大数据时代,很多维表比事实表还大,如淘宝几十亿的商品、几亿的买家等,在分布式数据仓库系统中,事实表和维表关联的成本很高。
所以在传统的维度模型设计完成之后,在物理实现中将各维度的常用属性退化到事实表中,以大大提高对事实表的过滤查询、统计聚合等操作的效率。
累计快照事实表特点
数据不断更新
事务事实表记录事务发生时的状态,对于实体的某一实例不再更新;而累积快照事实表则对实体的某一实例定期更新。
多业务过程日期
累积快照事实表适用于具有较明确起止时间的短生命周期的实体,比如交易订单、物流订单等,对于实体的每一个实例,都会经历从诞生到消亡等一系列步骤。
对于商品、用户等具有长生命周期的实体, 一般采用周期快照事实表更合适。
累积快照事实表的典型特征是多业务过程日期,用于计算业务过程之间的时间间隔。对于累积快照事实表,还有一个重要作用是保存全量数据。
对于淘宝交易,需要保留历史截至当前的所有交易数据,其中一种方式是在ODS 层保留和源系统结构完全相同的数据z 但由于使用时需要关联维度,较为麻烦,所以在公共明细层需要保留一份全量数据,淘宝交易累积快照事实表就承担了这样的作用一一存放加工后的事实,并将各维度常用属性和订单杂项维度退化到此表中。通常用于数据探查、统计分析、数据挖掘等。