数据建模:维度建模

维度建模

维度建模的设计步骤

1.数据调研
2.明确数据域
3.构建业务总线矩阵
4.明确统计指标
5.维度模型的设计(需求调研->选择业务过程-->确定业务过程所属数据域->确定粒度(粒度是维度和事实的结合体)->确定一致性维度->确定度量值)
6.汇总模型的设计

维度表的设计

维度表概述

维度表概述:维度表是维度建模的基础和灵魂。事实表紧紧围绕业务过程进行设计,而维度表则围绕业务过程所处的环境进行设计。在维度建模中,将度量称为“事实”将环境描述为“维度”,维度是用于分析事实所需要的多样环境。
维度表主要包含一个主键和各种维度字段,维度字段称为维度属性。
维度使用主键标识其唯一性,主键也是确保与之相连的任何事实表之间存在引用完整性的基础。
维度所包含的表示维度的列,称为维度属性。维度属性是查询约束条件、分组和报表标签生成的基本来源,是数据易用性的关键。维度的作用一般是查询约束、分类汇总以及排序等。
维度代理键:不具备业务含义,例如商品维度表,如果为每行数据生成一个主键自增的id.那么这个id就是维度代理键
维度自然键:具备业务含义.例如商品id就是商品维度表的自然键.
维度外键:事实表中用的标识维度信息的id,就是维度外键. 其实放维度自然键就好. 

维度表设计步骤

1.确定维度表:
    首先设计事实表时,已经明确了每个事实表的所有相关维度了.可能存在多个事实表与同一个维度都相关的情况,这种情况需保证维度的唯一性,即只创建一张维度表。理论上每个维度需要一个维度表.
    另外,如果某些维度表的维度属性很少,可以不创建维度表,而把该表的维度属性直接增加到与之相关的事实表中,这个操作称为维度退化。(只要有维度表中字段,放入到事实表中.就叫维度退化).支付中支付渠道,随着配置调整,所以这种支付渠道属性,最好退化到事实表中.
2.确定主维表和相关维表
    此处的主维表和相关维表均指业务系统中与某维度相关的表。维度表的粒度通常与主维表相同。
3.确定维度属性
    确定维度属性即确定维度表字段。维度属性主要来自于业务系统中与该维度对应的主维表和相关维表。维度属性可直接从主维表或相关维表中选择,也可通过进一步加工得到

注意事项

1.尽可能生成丰富的维度属性.维度属性是统计时分组(group by)的关键,维度属性的丰富程度直接影响到数据模型能够支持的指标的丰富程度
2.尽量不使用编码,而使用明确的文字说明,一般可以编码和文字共存
3.尽量沉淀出通用的维度属性.有些维度属性的获取需要进行比较复杂的逻辑处理,例如需要通过多个字段拼接得到。为避免后续每次使用时的重复处理,可将这些维度属性沉淀到维度表中。
4.不建议使用雪花模型,对于维度中可以理解为包含连续主从关系的属性层次,使用星型模型,进行反规范化,将维度的属性层次合并到单个维度中.
5.保持维度一致性:保证维度格式一致性,内容一致性
6.维度属性的整合,数仓可能对接不同应用系统,例如可能有业务系统,支付系统等,同一个账户id,这里命名user_id,那里命名uid.要将这些命名,字段类型,编码,等统一起来.
7.维度表的拆分和整合.例如业务系统中订单,会有订单单号. 但是支付系统中会跟三方交互,会有三方单号.虽然都是订单维度表,但是可能有细微字段差异,需要考虑是否整合,拆分,以及怎么整合,拆分.(常用的整合方式:1.设计主从维表,相关的属性放在主维度表,不同的属性放在从属维表2.直接合并,可能会有大量null,)
8.维度变化的问题:维度变化的问题,其实很多时候取决于业务.根据业务需要来决定维度变化是否保留.不保留就是全量最新维度,保留要么拉链表,要么日全量快照
9.维度的递归层次,按照层级是否固定分为均衡层次结构和非均衡层次结构。
    解决思路:1.层次结构扁平化降低递归层次使用复杂度的最简单和有效的方法是层次结构的扁平化,通过建立维度 的固定数级别的属性来实现,可以在一定程度上解决上钻和下钻的问题。对于均衡层次结构,采用扁平化最有效。但是对于非均衡层次结构,可以通过预留级别的方式来解决,       但扩展性较差。
    2.层次桥接表:在数据仓库的维度建模中,层次桥接表(Hierarchy Bridge Table)是一种处理复杂层次和多对多关系的技术。它提供了一种有效的方式来查询和分析数据。一个典型的例子是员工和他们的管理者之间的关系。在一个大的组织中,一个员工可能有一个直接上级,这个上级也可能有他/她自己的上级,一直到公司的最高层。这就形成了一个层次结构。在这种情况下,如果你想要查询或分析“所有由某个管理者管理的员工”,你需要遍历这个层次结构。层次桥接表就是为了解决这个问题而设计的。在层次桥接表中,每一行代表了一个员工和他/她的一个上级(可以是直接上级,也可以是间接上级)之间的关系。例如,如果员工A的直接上级是B,B的上级是C,那么在层次桥接表中,就会有两行数据:一行表示A和B的关系,另一行表示A和C的关系。通过查询层次桥接表,你可以很容易地找到所有由某个管理者(无论是直接还是间接)管理的员工。同时,你也可以通过查询这个表,找到一个员工的所有上级
    3.这里我想多说一句,层次桥接表解决了层次结构扁平化带来的问题:但是其加工逻辑复杂,使用逻辑复杂,而且由于事实表和桥接表的多对多的关系而带来了双重计算的隐患。在实际应用中可以根据具体的业务需求来选择技术方案,很多时候,简单、直接的技术方案却是最好的解决方案。
10.行为维度:行为维度普遍变化较快,要么极限存储(就是拉链表),要么主从维表
11.多值维度:事实表的一条记录在某维表中有多条记录与之对应。比如对于淘宝交易订单,买家一次购买了多种商品,如件毛衣和两双袜子,称为交易父订单 对于每种商品的交易,称为交易子订单:此交易父订单有两个子订单与之对应。假设设计交易父订单事实表,则对于此事实表的每一条记录,在商品表中都有多条记录与之对应。 
    处理方案:1.降低事实表的粒度 2.采用多字段,考虑到扩展性,可以通过预留宇段的方式. 3.桥接表(不推荐)
12.多值属性:维表中的某个属性字段同时有多个值,称之为“多值属性”。
    处理方案:1.一个字段采用map结构处理 2.添加多个属性字段(固定的话效果          好)3.加列,一个属性添加一列.不推荐
13.杂项维度:杂项维度是由操作型系统中的指示符或者标志宇段组合而成的,一般不在一致性维度之列。比如淘宝交易订单的交易类型宇段,包
括话费充值、司法拍卖、航旅等类型 :支付状态、物流状态等,它们在源系统中直接保存在交易表中。1个事实表中可能会存在多个类似的字段,如果作为事实存放在事实表中,则会导致事实表占用空间过大 如果单独建立维表,外键关联到事实表,则会出现维度过多的情况;如果将这些字段删除,则会有人不同意。这时,通常的解决方案就是建立杂项维度 ,将这些字段建立到维表中,在事实表中只需保存一个外键 即可。;同时,由 于在分布式
计算系统中生成代理键的复杂度,一般在逻辑建模中 ,会使用实体的主键作为杂项维度的主键。只考虑杂项维度,忽略其他维度.例如交易订单就可以做杂项维度.无线交易、订单的 attributes 属性.
总结下来就是:不在一致性维度表的字段,可以拼在一块做一张维度表. 

事实表的设计

事实表概述

事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度和与业务过程有关的度量。
事实表中一条记录所表达的业务细节程度被称为粒度。通常粒度可以通过两种方式来表述:一种是维度属性组合所表示的细节程度:一种是所表示的具体业务含义。
事实分为:可加性、半可加性和不可加性三种类型。
可加性事实:是指可以按照与事实表关联的任意维度进行汇总。
半可加性事实:只能按照特定维度汇总,不能对所有维度汇总,比如库存可以按照地点和商品进行汇总,而按时间维度把一年中每个月的库存累加起来则毫无意义。
不可加性事实:比如比率型事实。对于不可加性事实可分解为可加的组
件来实现聚集。
维度属性也可以存储到事实表中,这种存储到事实表中的维度列被称为“维度退化”
事实表有三类型事务事实表、周期快照事实表和累积快照事实表

事实表设计原则

1.尽可能包含所有与业务过程相关的事实
2.只选择与业务过程相关的事实:
在选择事实时,应该注意只选择与业务过程有关的事实。比如在订
单的下单这个业务过程的事实表设计中 ,不应该存在支付金额这个表示
支付业务过程的事实。
3.分解不可加性事实为可加的组件
比如订单的优惠率,应该分解为订单原价金额与订单优惠金额两个事实存储在事实表中。
4.在选择维度和事实之前必须先声明粒度.粒度是维度和事实的结合体,不同的粒度对应不同的维度,所以一定是先声明粒度
5.设计事实表的过程中,建议从最低级别的原子粒度开始
6.在同一个事实表中不能有多种不同粒度的事实
7.事实的单位要保持一致
8.对事实的 null 值要处理
9.使用退化维度提高事实表的易用性(这里看公司了,我是不建议在业务变更很快的周期内做退化,加字段刷数据太麻烦了.这里建议dwd=维度外键+度量值)
​

事务型事实表

概述
事务事实表用来记录各业务过程,它保存的是各业务过程的原子操作事件,即最细粒度的操作事件。粒度是指事实表中一行数据所表达的业务细节程度。
事务型事实表可用于分析与各业务过程相关的各项统计指标,由于其保存了最细粒度的记录,可以提供最大限度的灵活性,可以支持无法预期的各种细节层次的统计需求。
设计流程
1.选择业务过程及确定事实表类型。
2.确定数据域
2.声明粒度
3.确定维度
4.确定事实
5.冗余维度(这里看公司了,我是不建议在业务变更很快的周期内做退化,加字段刷数据太麻烦了.这里建议dwd=维度外键+度量值)
补充
分类以及对比(大数据之路写的,阿里根据自己情况设计的.具体怎么做看公司架构师怎么设计)
单事务事实表:即针对每个业务过程设计一个事实表。
多事务事实表:多事务事实表在设计时有两种方法进行事实的处理
1.不同事务过程的事实使用不同的事实字段进行存放,如果不是当前业务过程的度量,则采取零值处理方式。
2.不同业务过程的事实使用同一个事实字段进行存放,但增加一个业务过程标签
两种事务事实表对比:
1.不同业务过程的粒度相同,同时拥有相似的维度时,此时就可以考虑采用多事务事实表,不仅其加工计算成本
较低,同时在存储上也相对节省
2.单事务事实表在处理事实上比较方便和灵活,多事务事实表下游用户确实有一定的学习成本
3.若使用多事务事实表, 会导致事实表零值或空值字段较多。

周期型快照事实表

概述
周期快照事实表以具有规律性的、可预见的时间间隔来记录事实,主要用于分析一些存量型(例如商品库存,账户余额)或者状态型(空气温度,行驶速度)指标。
对于商品库存、账户余额这些存量型指标,业务系统中通常就会计算并保存最新结果,所以定期同步一份全量数据到数据仓库,构建周期型快照事实表,就能轻松应对此类统计需求,而无需再对事务型事实表中大量的历史记录进行聚合了。
对于空气温度、行驶速度这些状态型指标,由于它们的值往往是连续的,我们无法捕获其变动的原子事务操作,所以无法使用事务型事实表统计此类需求。而只能定期对其进行采样,构建周期型快照事实表。
设计流程
1.确定粒度:确定快照事实表的快照粒度。
周期型快照事实表的粒度可由采样周期和维度描述,故确定采样周期和维度后即可确定粒度。
采样周期通常选择每日。
维度可根据统计指标决定,例如指标为统计每个仓库中每种商品的库存,则可确定维度为仓库和商品。
确定完采样周期和维度后,即可确定该表粒度为每日-仓库-商品。
2.确认事实:确定快照事实表采样的状态度量。
事实也可根据统计指标决定,例如指标为统计每个仓库中每种商品的库存,则事实为商品库
补充
阿里的大数据之路:周期快照事实表还存在分类:
单维度的每天快照事实表(这就是统计周期历史至今的快照)
混合维度的每天快照事实表(一行数据粒度不统一,真的好吗?)
全量快照事实表(常规理解的的周期快照)

累积快照事实表

概述
累计快照事实表是基于一个业务流程中的多个关键业务过程联合处理而构建的事实表,如交易流程中的下单、支付、发货、确认收货业务过程。
累积型快照事实表通常具有多个日期字段,每个日期对应业务流程中的一个关键业务过程(里程碑)。
设计流程
1)选择业务过程
选择一个业务流程中需要关联分析的多个关键业务过程,多个业务过程对应一张累积型快照事实表。
2)声明粒度
精确定义每行数据表示的是什么,尽量选择最小粒度。
3)确认维度
选择与各业务过程都相关的维度(案例中订单id,用户id),需要注意的是,每各业务过程均需要一个日期维度。
4)确认事实
选择各业务过程的度量值。
补充
特殊处理的,业务流程不一定是都是固定的线性的
1.非线性过程(就是业务流程不是a->b->c->d.有可能分叉,循环,跳过等)
解决方案:
1.针对跳过的,保留全部流程字段,没有的给null
2.针对分叉循环的,保留关键流程,跟业务方商量保留哪些以及怎么保留.

公共汇总层(dws):

设计原则
1.数据公用性
2.不跨数据域(小公司也未尝不可,就是刷数据会麻烦.但是好用啊,相同粒度,相同统计周期的不同数据域的数据在一张表中)
3.区分统计周期
如何设计
我理解下来就是根据公司的指标进行拆解,把业务过程相同(或者数据域相同的,或者干脆不要)、统计周期相同、统计粒度相同的不同度量值和不同聚合逻辑放在一起.这就跟上述的设计原则对应上了.

个人理解和总结

通过学习市面上的一些资料.以及读数仓工具箱,和阿里的大数据之路,发现他们很多的东西都存在矛盾. 但是核心思想一致.核心思想就是:维度建模的流程:需求调研->选择业务过程->确定业务过程所属数据域->确定粒度(粒度是维度和事实的结合体)->确定一致性维度->确定度量值. 只是在里边细小的表设计会根据不同的业务场景有一些额外处理.
毕竟理论结合实践嘛,不犯经验主义错误,不犯冒进主义错误.根据维度建模核心思想,以及具体的业务场景进行设计,让模型好用,方便,提高效率,节省资源.保证数据的一致性,准确性.就是好的模型.
数仓的模型设计(这里包含公共汇总层),是一个从下往上,与从上往下同时夹的过程.dim/dwd 根据业务系统从下往上设计,dws层的设计根据需求(或者指标拆分)从上往下设计的过程.
上一篇:贪心算法|738.单调递增的数字


下一篇:Linux命令学习—linux 的文件系统