事实表结构
事实表中每一行对应一个度量事件,反之亦然,比如订单表,每一行对应一个用户下单的事件,此时如果下单送积分的话,那么积分应该对应一个新的积分表,因为积分和下单是不同的事件,不要把这两个事件混在同一个表中。
每个事件都对应一个度量,一般情况下是数字度量,比如用户下单事件对应的数字度量应该是订单金额。
事实表一般包含外键,用于关联与之相关的维度,也包含可选的退化维度键和日期/时间戳。
可加、半可加、不可加事实
事实表中的数字度量可以划分为三类,分别对应着可加、半可加、不可加事实。
① 可加事实
例如商品销售记录表,对应着商品销售事实,由于该事实的度量为销售金额是可加的(即可以累加),所以该事实为可加事实
② 半可加事实
半可加事实一般记录的是静态的度量数据(例如库存、价差额、账户余额),半可加度量可以对某些维度汇总,但不能对所有的维度汇总,例如时间维度,我们会发现在时间维度下的加法操作没有意义。例如:上一个月的总库存、上周的账户总余额,这些指标没有意义。
③ 不可加事实
在不可加事实中,它的度量是不可加的,例如:比率。对不可加事实,最好的方法是,尽可能的存储不可加度量的完全可加分量,并在计算出最终的不可加事实前,将这些分量汇总到最终的结果集中 (即计算比率的几个值称为不可加度量的完全可加分量)。最终计算通常发生在 BI 层或 OLAP 多维数据库层。
事实表中的空值
事实表中的可以存在空值度量。所有聚集函数 ( SUM、COUNT、MIN、MAX、AVG ) 均可对空值事实计算。然而,在事实表的外键中不能存在空值,否则会导致违反参照完整性的情况发生(无法查看关联表的数据)。
一致性事实(事实表中字段命名尽量保持统一)
如果某些度量出现在不同的事实表中,需要注意,如果需要比较或计算不同事实表中的事实,应保证针对事实的技术定义是相同的。如果不同的事实表定义是一致的,则这些一致性事实应该具有相同的命名。
如果事实表不能兼容,则应该有不同的命名用于告诫业务用户和 BI
用户。
笔者公司有一张事实表,该事实表记录了当前用户理财产品的持有金额(即用户的 AUM
),该事实表其实来自于多个不同的表事实,因为用户购买不同的理财产品可能会落在不同的表中。
事实是相同的,但是有的表中该度量字段命名为 fund_aum
,有的则为 prod_aum
,经了解,度量是相同的,只是命名不同。所以很容易出现歧义,因此相同的事实,度量字段命名尽量保持一致。
事务事实、周期性快照事实表、累计快照事实表、无事实的事实表
① 事务事实表
大多数的事实表都是事务事实表,事务事实表的每一行代表某个时间点的度量事件。事务事实表可以是稠密的,也可以是稀疏的,因为仅当存在度量是才会建立行。
该事实表一般会包含一个与维度表关联的外键
,也可能包含精确的时间戳
和退化的维度键
。
注意:度量数字事实必须与事务粒度保持一致。
② 周期性快照事实表
周期性快照事实表中的每行汇总了发生在某一标准周期,如某一天、某周、某月的多个度量事件。
周期性快照事实表的粒度是周期,而不是个体的事务。
周期快照事实表通常包含了许多事实,因为任何与事实表粒度一致的度量事件都被允许存在的。这些事实表其外键的密度是均匀的,因为即使周期内没有发生活动,也会在事实表中为每个事实插入包含 0 或空值的行。
③ 累计快照事实表
累计快照事实表的行汇总了发生在过程开始和结束之间可预测步骤内的度量事件。
④ 无事实的事务表
尽管多数度量事件获取的结果是数字化的,但也存在某些事件仅仅记录一系列某一时刻发生的多维实体。
例如,在给定的某一天中发生的学生参加课程的事件,可能没有可记录的数字化事实,但该事实行代又一个包含日期、学生、教师、地点、课程等定义良好的外键(即多维实体)。
⑤ 合并事实表
通常将来自多个过程的,以相同粒度表示的事实合并为一个单一的合并事实表,这样能够带来很大的方便。
例如,笔者公司的客户购买理财交易的数据来自多个业务数据库,有基金、债券、活期、定期等多种理财产品,每种理财产品的销售事实都记录在各自的表中。在ODS 层中,我们会将这些来自不同表的销售事实进行合并。这样在统计的时候就很方便。