数仓(二)关系建模和维度建模

浪尖聊大数据

共 5361字,需浏览 11分钟

 · 2022-01-13


上一篇我们了解了OLTP和OLAP数据处理类型。OLTP处理的是关系模型表即实体-关系表ER,而OLAP处理的是维度模型表


数仓(一)简介数仓,OLTP和OLAP


本篇我们来讨论一下数仓中两种建模的方式:关系建模和维度建模,特别是维度建模的4个步骤,是数仓领域核心重要内容,及数仓分层。


一、数据模型

数据模型就是数据组织和存储方法,它强调从业务、数据存取和使用角度合理存储数据。Linux的创始人Torvalds有一段关于“什么才是优秀程序员”的话:“烂程序员关心的是代码,好程序员关心的是数据结构和它们之间的关系”。

只有数据模型将数据有序的组织和存储起来之后,数据才能得到高性能、低成本、高效率、高质量的使用。
关于数仓的建模有两种基本的模型:
1、关系建模(Inmon)
关系建模是数据仓库之父Inmon推崇的、从全企业的高度设计一个3NF模型的方法,用实体加关系描述的数据模型描述企业和业务架构。在范式理论上符合3NF,站在企业角度面向主题的抽象,而不是针对某个具体业务流程的实体对象关系抽象。它更多是面向数据的整合和一致性治理,正如Inmon所希望达到的“single version of the truth”。
典型代表是雪花模型。
2、维度模型(Kimball)
是数据仓库领域另一位大师Ralph Kimball 所倡导的。维度建模以分析决策的需求出发构建模型,构建的数据模型为分析需求服务,因此它重点解决用户如何更快速完成分析需求,同时还有较好的大规模复杂查询的响应性能,更直接面向业务。
为什么维度建模是数据仓库/商业智能 项目成功的关键?
因为不管我们的数据量从GB到TG还是到PB,虽然数据量越来越大,但是数据展现要获得成功,就必须建立在简单性的基础之上,而维度建模就是时刻考虑如何能够提供简单性,以业务为驱动,以用户理解性和查询性能为目标。
典型的代表是我们比较熟知的星形模型。


二、事实表和维度表

维度模型分为:事实表和维度表;

我们看下面这个维度模型示意图:

红框:事实表SalesOrder

绿色圆形框:维度表Gender、Date、Product等



1、事实表
事实表(Fact Table)用来记录具体事件,包含了每个事件的具体要素,以及具体发生的事情。事实表是主干,简明扼要介绍一个事实。
上图事实表例子中就通过一条事实表记录:说明了某个地方(LocationId)的某人(用户CustomerId)在某个时间(时间DateId)买了某产品(产品ProductId)金额SalesAmount等。
事实表特征
  • 每一个事实表的行包括具有可加性的数值型的度量值;
  • 与维表相连接的外键,通常具有两个和两个以上的外键;
  • 记录非常的多行数多
  • 内容相对的窄即列数较少(主要是外键id和度量值)
  • 经常发生变化,每天会新增加很多

事实表又分为以下六类

1.1、事务型事实表

以每个事务或事件为单位,例如一个销售订单记录,一笔支付记录等,作为事实表里的一行数据。一旦事务被提交,事实表数据被插入,数据就不再进行更改,其更新方式为增量更新。
1.2、周期型快照事实表
周期型快照事实表,表中不会保留所有数据,只保留固定时间间隔的数据,例如每天或者 每月的销售额或每月的账户余额等。
例如购物车,有加减商品,随时都有可能变化,但是我们更关心每天结束时这里面有多少商品,方便我们后期统计分析。
1.3、累计型事实表
累计快照事实表用于跟踪业务事实的变化。例如,数据仓库中可能需要累积或者存储 订单从下订单开始,到订单商品被打包、运输、和签收的各个业务阶段的时间点数据来跟踪 订单声明周期的进展情况。当这个业务过程进行时,事实表的记录也要不断更新。

1.4、累无事实的事实表

我们以上讨论的事实表度量都是数字化的,当然实际应用中绝大多数都是数字化的度量,但是也可能会有少量的没有数字化的值但是还很有价值的字段,无事实的事实表就是为这种数据准备的,利用这种事实表可以分析发生了什么。
1.5、聚集类事实表
聚集,就是对原子粒度的数据进行简单的聚合操作,目的就是为了提高查询性能。如我们需求是查询全国所有支行的理财总销售额,我们原子粒度的事实表中每行是每个支行每个商品的销售额,聚集事实表就可以先聚合每个支行的总销售额,这样汇总所有支行的销售额时计算的数据量就会小很多。

1.6、合并事实

这种事实表遵循一个原则,就是相同粒度,数据可以来自多个过程,但是只要它们属于相同粒度,就可以合并为一个事实表,这类事实表特别适合经常需要共同分析的多过程度量。

2、维度表
维度表(Dimension Table )一般是对事实的描述信息。每一张维度表对应现实世界中的一个对象或者概念。
例如:用户、商品、日期、地区等。是依赖事实表而存在的,没有事实表数据,维度表也就没有存在的意义。每个维度表都是对事实表中的每个列/字段进行展开描述。比如:事实表中的用户ID,就可以进一步展开成一张维度表,记录该用户ID实体的用户名、联系信息、地址信息、年龄、性别和注册方式等等。
一般来说,对于数仓,事实表的增删改操作相比维度表更为频繁,模型建立后,维度表中的数据保持相对稳定。
维度表特征
  • 维度表的范围很宽(具有多个属性、列比较多)
  • 跟事实表相比,行数相对较小;
  • 内容相对固定:编码表。比如:城市行政编码表等

通过事实表和维度表组织起来的数仓多维数据模型,相比原本分散在数据库等各处的数据,能够有更有目的更高效的查询效率。比如可以查询汇总地域维度中某个省的商品销售情况,也可以通过时间维度分析每个季度的某类商品销售趋势。将多个维度表跟事实表进行不同程度的连接,可以展开得到各种各样的分析结果,满足商品运营等数据使用者的不同需求。



三、模型分类


在建模的基础上又分为常见的三种模型:星型模型、雪花模型、星座模型。


1、星型模型(Star Schema


星形模式(Star Schema)是最常用的维度建模方式。


一般星形模式的维度建模由一个事实表(SalesFactTable)和一组维度表(time、branch、item、location等)成。
具有以下特点:
  • 维度表只和事实表关联,维度表之间没有关联;
  • 每个维度表的主键为单列,且该主键放置在事实表中,作为两边连接的逻辑外键;
  • 以事实表为核心,维度表围绕核心呈星形分布

每个维度都有一个维作为主键,所有这些维度表主键组合成事实表的主键。强调的是对维度进行预处理,将多个维度集合到一个事实表,形成一个宽表。这也是我们在使用比如:hive时,经常会看到一些大宽表的原因,大宽表一般都是事实表,包含了维度关联的主键和一些度量信息,而维度表则是事实表里面维度的具体信息,使用时候一般通过join来组合数据,相对来说对OLAP的分析比较方便。

2、雪花模型((Snowflake Schema)


雪花模式(Snowflake Schema)当有一个或多个维度表没有直接连接到事实表上,而是通过其他维度表连接到事实表上时,称雪花模型。每个维度表可继续向外连接多个子维度表。(三范式代表作)

比如:这里SalFactTable是事实表,location作为一维维度表,city是二维维度表



雪花模型是对星型模型的扩展。它对星型模型的维表进一步层次化,原有的各维表可能被扩展为小的事实表,形成一些局部的 “层次 ” 区域,这些被分解的表都连接到主维度表而不是事实表。

星形模式中的维度表相对雪花模式来说要大,而且不满足规范化设计。雪花模型相当于将星形模式的大维表拆分成小维表,满足了规范化设计。

雪花模型更加符合数据库范式,减少数据冗余,但是在分析数据的时候,操作比较复杂,需要join的表比较多所以其性能并不一定比星型模型高。

雪花模型和星型模型的区别:

在于维度的层级,标准的星型模型维度只有一层,而雪花模型涉及多层维度

然而这种模式在实际应用中很少见,因为这样做会导致开发难度增大因为join太多,hadoop体系会增加资源开销,而数据冗余问题在数据仓库里并不严重。

3、星座模型(Fact Constellations Schema)


星座模式(Fact Constellations Schema)也是星型模式的扩展。前面两种维度建模方法都是多维表对应单事实表,但在很多时候维度空间内的事实表不止一个,而一个维度表也可能被多个事实表用到。



星座模型和星型、雪花型模型区别:

主要在于事实表的数量,星型和雪花型一般是基于1个事实表,而星座模型是基于多个事实表。

在实际业务开发中,因为数仓有海量多个事实表的,并且会共享一些维度,不会选择单一的一种模型,会多个模型混合是常态。单一层维度和多层维度并存。星座模式将作为最主要的维度建模。但是总体上需要注意的是要尽量减少星型模型的维度,因为hadoop体系,减少join就意味着减少shuffle,减少资源。



四、维度建模4步骤


我们知道事实表,维度表,星形模型,雪花模型、星座模型这些概念了,但是实际业务中,我们怎么根据海量的业务数据进行数仓建设呢
根据《数仓工具箱》书中的维度建模四步:


1、选择业务过程

维度建模必须以业务为根基进行建模,那么选择业务过程,就是在整个业务流程中选取我们需要建模的业务,根据公司业务提供的需求及日后的易扩展性等进行选择业务。比如:银行理财业务,整个理财业务有几十种产品,每种不通同的产品期限不一致,募集期不一样,有些是手机客户端可以购买,有些事现场双录才能购买,有些是私行购买,有些事个人达到一定条件即可购买,也有一些是企业客户名单制购买。业务选择非常重要,因为后面所有的步骤都是基于此业务数据展开的。

2、声明粒度

首先说明一下,粒度这个概念是数仓建模极其重要的一个概念,我们后期会单独讲解数仓中重要的两个概念:粒度和分区。

这里先举个例子:对于用户(这个主题)来说,一个用户有一个身份证号,一个户籍地址,多个手机号,多张银行卡,那么与用户粒度相同的粒度属性有身份证粒度,户籍地址粒度,比用户粒度更细的粒度有手机号粒度,银行卡粒度,存在一对一的关系就是相同粒度。
为什么要相同粒度呢?
因为维度建模中要求我们,在同一事实表中,必须具有相同的粒度,同一事实表中不要混用多种不同的粒度,不同的粒度数据建立不同的事实表。并且从给定的业务过程获取数据时,强烈建议从关注原子粒度开始设计,也就是从最细粒度开始,因为原子粒度能够承受无法预期的用户查询。但是上卷汇总粒度对查询性能的提升很重要的,所以对于有明确需求的数据,我们建立针对需求的上卷汇总粒度,对需求不明朗的数据我们建立原子粒度。
实际应用:
声明粒度意味着精确定义事实表中的一行数据表示什么,应该尽可能选择最小粒度,以此来应各种各样的需求。不做聚合操作。
典型的粒度声明如下:
  • 订单事实表中一行数据表示的是一个订单中的一个商品项;
  • 支付事实表中一行数据表示的是一个支付记录;


3、确认维度


维度表是作为业务分析的入口和描述性标识,维度的主要作用是描述业务是事实,主要表示的是“谁,何处,何时”等信息。在一堆的数据中怎么确认哪些是维度属性呢,如果该列是对具体值的描述,是一个文本或常量,某一约束和行标识的参与者,此时该属性往往是维度属性,掌握事实表的粒度,就能将所有可能存在的维度区分开,并且要确保维度表中不能出现重复数据,应使维度主键唯一。
确定维度的原则
后续需求中是否要分析相关维度的指标。例如,需要统计,什么时间下的订单多,哪个地区下的订单多,哪个用户下的订单多。需要确定的维度就包括:时间维度、地区维度、用户维度。

4、确认事实


此处的“事实”一词,指的是业务中的度量值(次数、个数、件数、金额,可以进行累加),例如订单金额、下单次数等。事实表中的每行对应一个度量,每行中的数据是一个特定级别的细节数据,即粒度。
维度建模的核心原则之一是同一事实表中的所有度量必须具有相同的粒度。这样能确保不会出现重复计算度量的问题。
怎么确定是事实属性还是维度属性?
判断原则是:事实表数值类型和可加类事实。所以可以通过分析该列是否是一种包含多个值并作为计算的参与者的度量,这种情况下该列往往是事实。
确认事实一般在数仓的DWD(Data Warehouse Detail)层,后面会讲解数据仓库的分层,以业务过程为建模驱动,基于每个具体业务过程的特点,构建最细粒度的明细层事实表。事实表可做适当的宽表化处理。为了应对更复杂的业务需求,可以将能关联上的表尽量关联上。
如何判断是否能够关联上呢?
在业务表关系图中,只要两张表能通过中间表能够关联上,就说明能关联上


  • 横轴:表示维度

  • 纵轴:表示事实

  • 度量值:从关系表里面找相应字段


至此,维度建模4步骤已经完成,这四步是必须按照顺序执行。

其实数仓建模中还有些其他建模体系:

像DataVault、Anchor模型,这两个模型感兴趣的可以参考浪尖下面的文章。

推荐阅读

数仓建模方法论

维度建模技术实践——深入事实表

聊聊维度建模的灵魂所在——维度表设计

漫谈数据仓库之维度建模


浏览 194
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报