维度模型系列文章:
。。。
更多最新文章请文末扫码关注公众号查看
1引言
上篇文章中我们主要介绍了事实类型(可加性、半可加性,不可加性),粒度,事实表三种类型主要内容,这篇文章我们继续介绍事实表其他相关内容:
- 父子型事实表
- 退化维
- 代理键
- 一致性事实
- 事实表设计方法
2父子型事实表
父子数据关系是业务领域常见的一种数据结构。例如,一个订单除了一条总的订单数据外还会包含许多行商品明细数据,其他的示例如提货单,保险索赔,零售发票等。
这种父子结构会带来典型的设计两难局面:有些数据仅在父级别可用(如:运费,订单满减金额,支付金额),而有些仅在子级别可用(如每种商品的数量,总价)。维度模型中需要两个事实表还是只要一个?在希望向下钻取到子级别时又要如何处理仅在父级别可用的数据呢?
以销售订单为例,假如我们按父子订单分别设计如下图所示的两张事实表,表面上看起来是两个不错的事实表,但是这样的设计存在一个问题,那就是在对产品进行汇总分析时,无法处理父订单级别的运费,支付金额,满减折扣等。
为了解决这个问题,可以将父级别的数据向下分配到子明细数据级别。采用事实粒度一致性原则,将父粒度数据按照某种规则分配到子粒度,用一张明细事实表来代替上面两个事实表,如下图所示,这样就可以按商品来汇总计算运费,优惠金额等数据了。
前面提到的分配规则是需要和业务人员提前达成的某种规则共识,但是有时候不同部门可能就某种分配方法无法达成共识,例如运费分摊的规则可能有按体积,按重量,按价值来分配。这时候我们可以按不同的分配规则计算多个事实放在事实表中,让任何人都可以使用这三种分配方法的任何一种来汇总业务数据,如:
- 按体积分配的运费金额
- 按重量分配的运费金额
- 按价值分配的运费金额
3退化维
对于订单,提货单,零售发票等父子型事实来说,很容易构想出相关的维度,但是订单号,发票号,提货单号如何处理呢?这些编号一般是父-子关系的父标题键,应该将这些编号直接加到事实表中,因为这些编号相关的信息已经都存在事实表中的维度了,没有其他属了,我们称他为退化维。
退化维还有一种使用场景:有时候我们为了使用方便,减少表关联操作,会将常用的维度信息放在事实表中。通过增加冗余存储的方式减少计算开销,提高使用效率。
4代理键
维度表主键标识其唯一性,主键也是维表和事实表关联的基础。主键有两种:自然键和代理键。代理键不具有业务含义,主要用于处理缓慢变化维(维表设计时详细介绍)。自然键具有业务含义。如商品,在ETL开发时,对于商品维表的每一行我们可以生成一个唯一的代理键与之对应,事实表存储这个代理键就可以了,而不是存储业务系统的商品ID。
关于代理键的详细内容我们在维度表技术章节在介绍。
5一致性事实
《数据仓库总线架构》中我们介绍了一致性维度,将不同业务过程按照一致性维度集成到一起。完成了数据仓库数据集成的80%任务。剩下的20%工作就是建立标准的,一致性化的事实定义。
一致性事实主要需要保证两点:第一个事实的定义及计算方法要一致,第二个是事实的单位要一致
在不同的事实表中,一些相同命名的事实的底层计算公式必须是相同,如收益,利润,标准价格,标准成本等。
6事实表设计方法
维度模型设计采用四步设计方法:选择业务过程、声明粒度、确定维度、确定事实。
- 选择业务过程
设计过程的第一步是确定要建模的业务过程和度量,这些业务过程是在业务需求收集过程中明确下来的
- 声明粒度
一旦业务过程被确定下来,就必须声明事实表的粒度,清楚定义事实表的行到底代表什么。一般的事实表粒度的选择应尽可能是最小的原子单元。在最小粒度的数据上设计出来的事实表是最健壮的设计。和那些粒度较大的数据相比,原子数据在响应突如其来的新查询和未预料到的数据加工方面具有更好的表现。
- 识别维度
一旦事实表的粒度已经确定下来,就意味着确定了主键。对应的维度组合和相关的维度字段j就能确定了
- 识别事实
最后一步是仔细选择适用于业务过程的事实和指标,且事实的粒度要与所声明的事实表的粒度一致。
更多技术文章请关注公众号: