事实表设计
事实表基础
事实表特性
-
通过获取描述业务过程的度量来表达业务过程,包含了引用的维度和与业务过程有关的度量
-
事实表中一条记录所表达的业务细节程度被称为粒度
-
粒度两种表达方式
- 一种是维度属性组合所表示的细节程度
- 一种是所表示的具体业务含义
-
-
作为度量业务过程的事实
-
整型或浮点型的十进制数值
-
可加性
- 可加性事实是指可以按照与事实表关联的任意维度进行汇总
-
半可加性
- 可加性事实只能按照特定维度汇总,不能对所有维度汇总,如库存只能指定条件可加无法日期汇总
-
不可加性
- 比率型事实,可分解为可加的组件来实现聚集
-
-
维度属性也可以存储到事实表中,这种存储到事实表中的维度列被称为“退化维度”
-
事实表的三种类型
-
事务事实表
- 用来描述业务过程,跟踪空间或时间上某点的度量事件,保存的是最原子的数据,也称为“原子事实表“
-
周期快照事实表
- 以具有规律性的、可预见的时间间隔记录事实 ,时间间隔如每天、每月、每年等
-
累积快照事实表
- 用来表述过程开始和结束之间的关键步骤事件 ,覆盖过程的整个生命周期
- 通常具有多个日期字段来记录关键时间点, 当过程随着生命周期不断变化时,记录也会随着过程的变化而被修改。
-
事实表设计原则
-
原则 1 :尽可能包含所有与业务过程相关的事实
- 分析哪些事实与业务过程有关是设计中非常重要的关注点
- 尽量包含所有与业务过程相关的事实
- 事实通常为数字型,即使冗余带来的存储开销也不会很大
-
原则 2 :只选择与业务过程相关的事实
- 比如在订单的下单这个业务过程的事实表设计中 ,不应该存在支付金额这个表示支付业务过程的事实
- 上述的观点不可沟通,具体要看改事实表所处的数仓层级和事实表的业务范围,其次下单业务也同样包含支付结果
-
原则 3 : 分解不可加性事实为可加的组件
- 比如订单的优惠率,应该分解为订单原价金额与订单优惠金额两个事实存储在事实表中
-
原则 4:在选择维度和事实之前必须先声明粒度
- 每个维度和事实必须与所定义的粒度保持一致
- 建议从最低级别的原子粒度开始
- 聚集性事实表的粒度描述,可采用维度或维度属性组合的方式
-
原则 5 : 在同一个事实表中不能有多种不同粒度的事实
- 案例主订单与子订单维度事实表,需要做到度量拆分,相对扩展性差
-
原则 6 :事实的单位要保持一致
- 如原订单金额、订单优惠金额、订单运费金额这三个事实
- 该采用一致的计量单位,统一为元或分,以方便使用
-
原则 7 : 对事实的 null 值要处理
- 因为数据库中 null 值对常用数字型字段的 SQL 过滤条件都不生效
- 比如大于、小于、等于、大于或等于、小于或等于,建议用零值填充
-
原则 8 :使用退化维度提高事实表的易用性
- 大数据领域中在事实表中存储各种类型的常用维度信息
- 通过增加冗余存储的方式减少计算开销,提高使用效率
事实表设计方法
-
Kimball的四步设计方法:选择业务过程、声明粒度、确定维度、确定事实
-
改良版步骤
-
第一步 : 选择业务过程及确定事实表类型
-
业务整个生命周期分析、明确关键业务步骤、选择与需求有关业务过程(淘宝订单例图)
-
业务过程通常使用行为动词表示业务执行的活动
-
单流转的业务过程
- 创建订单
- 买家付款
- 卖家发货
- 买家确认收货
-
选择相应的业务过程确定事实表类型
-
-
-
第二步:声明粒度
- 意味着精确定义事实表的每一行所表示的业务含义
- 粒度传递的是与事实表度量有关的细节层次
- 尽量选择最细级别的原子粒度
-
第三步 : 确定维度
-
选择能够描述清楚业务过程所处的环境的维度信息
比如在淘宝订单付款事务事实表中,粒度为子订单,相关的维度有买家、卖家、商品、收货人信息 、 业务类型、订单时间等维度。
-
-
第四步 . 确定事实
-
事实可以通过回答“过程的度量是什么”来确定
比如在淘宝订单付款事务事实表中,同粒度的事实有子订单分摊的支付金额、邮费、优惠金额等。
-
-
第五步 . 冗余维度
-
冗余部分维度,退化维度处理
比如在淘宝订单付款事务事实表中,通常会冗余大量的常用维度字段,以及商品类目、卖家店铺等维度信息。
-
-
事务事实表
事务事实表阐述
- 即针对一系列业务过程构建的一类事实表
- 用以跟踪定义业务过程的个体行为
- 提供丰富的分析能力
- 作为数据仓库原子的明细数据
设计过程
以淘宝交易事务事实表为例,阐述事务事实表的一般设计过程。
-
选择业务过程
- 创建订单、买家付款、 卖家发货、买家确认收货,即下单、支付 、发货和成功完结四个业务过程
-
确定粒度
-
淘宝订单的产生过程
-
淘宝出售商品主要分两类卖家
- 一类是个人性质的闲置卖家,主要出售闲置的或者二手商品
- 一类是拥有店铺的卖家,以出售新商品为主
-
交易订单两种方式
-
一种是选定商品后直接购买,这样会产生一个交易订单
-
一种是将多种商品加入到购物车中,然后一起结算
-
此时每一种商品都会产生一个订单 ,即子订单
- 子订单记录了父订单的订单号,并且有子订单标志
-
同时对于同一个店铺会额外产生一个订单,即父订单
- 父订单会承载订单物流、店铺优惠等信息
-
如果在同一个店铺只购买了一种商品,则会将父子订单进行合并
-
-
-
-
为每个业务过程确定一个粒度
-
其中下单、支付和成功完结三个业务过程选择交易子订单粒度
- 即每个子订单为事务事实表的一行
- 每个子订单所表达的细节信息为: 交易时间、卖家、买家、商品
-
卖家发货这个业务过程可以选择子订单粒度(实际操作调整为物流单粒度)
- 即将每个子订单作为卖家发货事实表 的一个细节
- 在实际操作中发现,卖家发货更多的是物流单粒度而非子订单粒度
- 同一个子订单可以拆开成多个物流单进行发货
-
-
-
确定维度
-
在淘宝交易事务事实表设计过程中,按照经常用于统计分析的场景,确定维度
- 包含:买家、卖家、商品、商品类目、发货地区、收货地区、父订单维度以及杂项维度
- 对于这些使用较多却又无法归属到上述买卖家或商品维度中的属性,则新建一个杂项维度进行存放
-
-
确定事实
-
选定三个业务过程一下单、支付和成功完结,不同的业务过程拥有不同的事实
-
下单业务过程
- 下单金额、下单数量、下单分摊金额
-
支付业务过程
- 支付金额、分摊邮费、折扣金额、红包金额、积分金额
-
完结业务过程
- 确认收货金额
-
-
由于粒度是子订单,则一些父订单金额需要分摊到子订单上
- 比如父订单邮费、父订单折扣
-
-
冗余维度
-
使下游分析使用模型更加方便
-
提高对事实表进行过滤查询、统计聚合的效率
-
是否退化维度事实表对比(宽表)
-
非退化维事实表
- 实例图
- 实例图
-
退化维事实表(宽表)
- 实例图
- 实例图
-
-
单事务事实表
-
即针对每个业务过程设计一个事实表
-
1688 交易流程则采用这种模式构建事务事实表
-
交易流程与淘宝类似但采用下单与支付两个单事务表设计
- 实例图
- 实例图
多事务事实表
-
将不同的事实放到同一个事实表中,即同一个事实表包含不 同的业务过程
-
两种方法进行事实的处理
- 不同业务过程的事实使用不同的事实字段进行存放
- 不同业务过程的事实使用同一个事实字段进行存放,但增加一个业务过程标签
-
设计方法阐述
-
淘宝交易事务事实表
书中给出了淘宝交易订单域的多事务事实表与下单和支付的单事务事实表,这边我觉得不太合理,就没有放出来说明。
多事务事实表目前通用的宽表最终状态的事务表无争议,但是在单事务的表中又存在了业务日期和下单日期去表示订单,导致一条订单明细存在不同业务日期有多条记录。活生生的把事实表做成了快照的模式,感觉多此一举。
当然可能阐述单事务表结合业务日期有日志的处理方式。- 使用不同事实字段进行存放的设计模式
- 如果不是当前业务过程的度量,则采取零值处理方式
- 即针对每个业务过程打一个标签
-
淘宝收藏商品事务事实表
-
使用不同业务过程使用同一个字段保存事实设计模式
-
包含了两个业务过程 : 收藏商品和删除商品
-
使用 一个“收藏事件类型”字段来区分是收藏商品还是删除商品
-
上面订单使用日志觉得不合理的地方在收藏中可以完美适用日志的模式
-
收藏商品明细
-
收藏商品事务事实表数据实例
-
-
-
-
多事务事实表的选择
-
冗余事实字段
- 适用:当不同业务过程的度量差异较大时,非当前业务过程则置零表示
- 缺点:度量字段零值较多
-
打标方式处理
- 适用:当不同业务过程的度量比较相似、差异不大时
- 缺点:在同一个周期内会存在多条记录
-
两种事实表对比
-
业务过程
-
单事务事实表:一个业务过程建立一个事实表
-
多事务事实表:在同一个事实表 中反映多个业务过程
-
选择单与多场景
- 首先需要分析不同业务过 程之间的相似性和业务源系统
- 比如淘宝交易的下单、支付和成功完结这三个业务过程是存在相似性的
- 都属于订单处理中的一环,并且都来自于交易系统
-
-
粒度和维度
- 当不同业务过程的粒度相同,同时拥有相似的维度时,此时就可以考虑采用多事务事实表
- 如果粒度不同,则必定是不同的事实表
-
事实
- 单事务事实表在处理事实上比较方便和灵活,仅仅体现同一个业务过程的事实即可
- 而多事务 事实表由于有多个业务过程, 所以有更多的事实需要处理
-
下游业务使用
- 单事务事实表对于下游用户而言更容易理解 , 关注哪个业务过程就使用相应的事务事实表
- 而多事务事实表包含多个业务过程,用户使用时往往较为困惑,有一定的学习成本
-
计算存储成本
- 当业务过程数据来源于同一个业务系统,具有相同的粒度和维度,且维度较多而事实相对不多时,此时可以考虑使用多事务事实表
- 不仅其加工计算成本较低,同时在存储上也相对节省,是一种较优的处理方式
-
表格对比图
父子事实的处理方式
- 子订单金额拆分图
事实的设计准则
-
事实完整性
- 包含与其描述的过程有关的所有事实
- 即尽可能多地获取所有的度量
-
事实一致性
- 明确存储每一个事实以确保度量的一
致性
- 明确存储每一个事实以确保度量的一
-
事实可加性
- 更多的是存储可加性各类金额的度量
- 下游用户在聚合统计时更加方便
周期快照事实表
特性
-
快照有事实表对比
- 事务事实表的粒度能以多 种方式表达,但快照事实表的粒度通常以维度形式声明
- 事务事实表是稀疏的,但快照事实表是稠密的
- 事务事实表中的事实是完全可加的,但快照模型将至少包含一个用来展示半可加性质的事实
-
用快照采样状态
- 快照事实表以预定的间隔采样状态度量
- 间隔联合一个或多个维度,将被用来定义快照事实表的粒度
- 举例:淘宝交易卖家自然年汇总事实表
-
快照粒度
- 快照事实表的粒度通常总是被多维声明
- 可以简单地理解为快照需要采样的周期以及什么将被采样
-
密度与稀疏性
- 快照事实表是稠密的
- 无论当天是否有业务过程发生,都会记录一行
-
半可加性
- 半可加性事实不能根据时间维度获得有意义的汇总结果
- 快照事实表在每个采样周期内是不能对状态度量进行汇总的
实例
-
设计步骤
- 确定快照事实表的快照粒度
- 确定快照事实表采样的状态度量
-
单维度的每天快照事实表
-
确定粒度
- 采样周期为每天,针对卖家、买家、商品、类目 、地 区等维度的快照事实表
-
确定状态度量
- 针对粒度确定需要采样的状态度量
-
比如淘宝卖家历史至今汇总事实表
-
-
混合维度的每天快照事实表
- 采样周期内多个维度进行采样
- 比如淘宝买卖家历史至今快照事实表
-
淘宝卖家信用分和 DSR 快照事实表
- 直接使用操作型系统的数据作为周期快照事实表的数据源
- 每天针对卖家维度统计卖家信用分和 DSR 评分
-
全量快照事实表
- 淘宝好中差评快照事实表
- 淘宝好中差评快照事实表
注意事项
-
事务与快照成对设计
- 互相补充,以满足更多 的下游统计分析需求
-
附加事实
- 附加一些上一个采样周期的状态度量
-
周期到日期度量
累积快照事实表
针对淘宝交易,设计了淘宝交易下单/支付/确认收货事务事实表,用于统计下单/支付/确认收货的子订单数、 GMV 等。但仍然有很多需求,此事务事实表很难满足,比如统计买家下单到支付的时长、买家支付到卖家发货的 时长、买家从下单到确认收货的时长等。如果使用事务事实表进行统计,则逻辑复杂且性能很差。对于类似于研究事件之间时间间隔的需求,采用累积快照事实表可以很好地解决。
设计过程
- 第一步 : 选择业务过程
- 第二步:确定粒度
- 第三步:确定维度
- 第四步:确定事实
- 第五步:退化维度
实例
-
淘宝交易累积快照事实表
管这玩意叫累积快照事实表,突然给我整不会了都,上面白看来都。这边理解累积就是状态的累积,一直到最终状态的结果。下面特性还有介绍
特点
-
数据不断更新
- 事务事实表记录事务发生 时的状态,对于实体的某一实例不再更新
- 累积快照事实表则对实体的某一实例定期更新
-
多业务过程日期
- 具有较明确起止时间的短生命周期的实体
- 保存全量数据
-
特殊处理
-
非线性过程
-
如淘宝订单下单到收货过程,并非全流程都要包含的业务过程
-
处理情况
-
业务过程的统一
- 如订单业务统一可以看成交易结束,无论是交易完成还是结束都视为统一结束标志
-
针对业务关键里程碑构建全面的流程
- 即使全流程未发生,但相关业务时间和事实置空
-
循环流程的处理
- 如一个业务存在多个业务里程碑日期,则使用首次还是最后一次发生日期,决定权在商业用户并非研发或设计人员
-
-
-
多源过程
- 举例:退款相关业务过程加入订单模型中,则需要和商业用户确定存在多次退款时如何取舍,确保模型粒度不变。
-
业务过程取舍
-
合理的选择事实表的相关业务过程
将退款相关业务流程设计进入交易累积快照事实表时 ,是否需要所有的业务过程?答案是否定的。当拥有大量的业务过程时,模型的实现复杂度会增加,特别是对于多源业务过程,模型的精合度过高,此时需要根据商业用户需求,选取关键的里程碑。
-
-
-
物理实现
-
第一种方式是全量表的形式
- 每天的分区存储昨天的全量数据和当天的增量数据合并的结果,保证每条记录的状态最新
- 适用于全量数据较少的情况
- 数量大全量表数据量不断膨胀,存储了大量永远不再更新的历史数据,对ETL与分析统计性能影响较大
-
第二种方式是全量表的变化形式
- 较短生命周期的业务实体一般从产生到消亡都有一定的时间间隔,可以测算周期,比如订单200天状态结束
- 设计最近 200 天的交易订单累积快照事实表
- 而 200 天之前的订单则按照 gmt_create 创建分区存储在归档表中
-
第三种方式是以业务实体的结束时间分区
-
每天的分区存放当天结束的数据
-
设计一个时间非常大的分区,比如 3000-12-31 ,存放截至当前未结束的数据
-
可能存在极特殊情况无实体结束时间处理方法
-
第一种方式 ,使用相关业务系统的业务实体的结束标志作为此业务系统的结束标志
比如针对物流订单,可以使用 交易订单。理论上 , 交易订单完结了,则物流订单已经完结。
-
第二种方式 ,和前端业务系统确定口径或使用前端归档策略
-
-
-
三种事实表的比较
- 三种事实表表格比较
无事实的事实表
不包含事实或度的事实表称为“无事实的事实表“
举例两种类型
-
第一种是事件类的,记录事件的发生
- 浏览日志
-
第二种是条件、范围或资格类的,记录维度与维度多对多之 间的关系
- 比如客户和销售人员的分配情况、产品的促销范围 等
聚集型事实表
看上去就是一些聚合事实表的集市的处理
聚集的基本原则
-
一致性
- 聚集表必须提供与查询明细粒度数据一致的查询结果
-
避免单一表设计
- 不要在同 一个表中存储不同层次的聚集数据
-
聚集粒度可不同
- 聚集并不需要保持与原始明细粒度数据一样的
粒度
- 聚集并不需要保持与原始明细粒度数据一样的
聚集的基本步骤
- 第一步:确定聚集维度
- 第二步:确定一致性上钻
- 第三步:确定聚集事实
阿里公共汇总层
-
基本原则
-
数据公用性
-
不跨数据域
- 多指ETL处理过程跨数据层向下清洗
-
区分统计周期
- 在表的命名上要能说明数据的统计周期
- 如_1d表示最近 1天_td 表示截至当天,_nd 表示最近 N 天
-
-
交易汇总表设计
-
针对订单表潜在聚集分析
-
设计流程
-
按商品粒度汇总
- 确定聚集维度一一商品
- 确定一致性上钻一一按商品(商品 ID )最近 1天汇总
- 确定聚集事实一一下单量、交易额
-
按卖家粒度汇总
- 确定聚集维度—卖家
- 确定一致性上钻一一按卖家(卖家 ID )最近 7 天和最近30天汇总
- 确定聚集事实一一交易额
-
按卖家、买家、商品粒度汇总
- 确定聚集维度一一卖家、买家 、商品
- 确定一致性上钻一一按卖家(卖家 ID ) 、买家(买家 ID )、 商品(商品 ID )最近1天汇总
- 确定聚集事实一交易额
-
-
聚集补充说明
-
聚集是不跨越事实的
- 聚集是针对原始星形模型进行的汇总
- 聚集的维度和度量必须与原始模型保持一致
-
聚集带来的问题
- 增加 ETL 维护的难度