数仓建模方法总结

2,113 阅读23分钟

一. 数据仓库建模的目的?

为什么要进行数据仓库建模?大数据的数仓建模是通过建模的方法更好的组织、存储数据,以便在 性能、成本、效率和数据质量之间找到最佳平衡点。一般主要从下面四点考虑

  • 访问性能:能够快速查询所需的数据,减少数据I/O
  • 数据成本:减少不必要的数据冗余,实现计算结果数据复用,降低大数 据系统中的存储成本和计算成本
  • 使用效率:改善用户应用体验,提高使用数据的效率
  • 数据质量:改善数据统计口径的不一致性,减少数据计算错误 的可能性,提供高质量的、一致的数据访问平台

二. 主流数仓建模方法:范式模型和维度建模

范式模型

将事物抽象为“实体”、“属性”、“关系”来表示数 据关联和事物描述;实体:Entity,关系:Relationship,这种对数据的抽象 建模通常被称为ER实体关系模型
ER模型是数据库设计的理论基础,当前几乎所有的OLTP系统 设计都采用ER模型建模的方式,且该建模方法需要满足3NF。Bill Inom提出的数仓理论,推荐采用ER关系模型进行建模,BI架构提出分层架构,数仓底层ods、dwd也多采用ER关系模型就行设计。
但是逐渐随着企业数据的高增长,复杂化,数仓全部使用ER模型建模 显得越来越不合时宜。为什么呢,因为其按部就班的步骤,三范式等,不适合现代化复杂,多变的业务组织。
范式建模就是将源表抽取为实体表,关系表,所以范式建模即是实体关系(ER)模型。数据没有冗余,符合三范式设计规范。

E-R模型建模的步骤(满足3NF)如下:

  1. 抽象出主体         (教师,课程)
  2. 梳理主体之间的关系   (一个老师可以教多门课,一门课可以被多个老师教)
  3. 梳理主体的属性    (教师:教师名称,性别,学历等)
  4. 画出E-R关系图

维度建模

维度建模,是数据仓库大师Ralph Kimball提出的,是数据仓库工程领域最流行的数仓建模经典。 维度建模以分析决策的需求出发构建模型,构建的数据模型为分析需求服务,因此它重点解决用户如何更快速完成分析需求,同时还有较好的大规模复杂查询的响应性能。维度建模是面向分析的,为了提高查询性能可以增加数据冗余,反规范化的设计技术。

Ralph Kimball提出对数据仓库维度建模,并且将数据仓库中的表划分为事实表、维度表两种类型。

1.事实表

在ER模型中抽象出了有实体、关系、属性三种类别,在现实世界中,每一个操作型事件,基本都是发生在实体之间的,伴随着这种操作事件的发生,会产生可度量的值,而这个过程就产生了一个事实表,存储了每一个可度量的事件。
以电商行业为例:电商场景:一次购买事件,涉及主体包括客户、商品、商家,产生的可度量值 包括商品数量、金额、件数等

image.png 事实表根据粒度的角色划分不同,可分为事务事实表、周期快照事实表、累积快照事实表。注意:这里需要值得注意的是,在事实表的设计时,一定要注意一个事实表只能有一个粒度,不能将不同粒度的事实建立在同一张事实表中。

事务事实表,用于承载事务数据,通常粒度比较低,它是面向事务的,其粒度是每一行对应一个事务,它是最细粒度的事实表,例如产品交易事务事实、ATM交易事务事实。 周期快照事实表,按照一定的时间周期间隔(每天,每月)来捕捉业务活动的执行情况,一旦装入事实表就不会再去更新,它是事务事实表的补充。用来记录有规律的、固定时间间隔的业务累计数据,通常粒度比较高,例如账户月平均余额事实表。 累积快照事实表,用来记录具有时间跨度的业务处理过程的整个过程的信息,每个生命周期一行,通常这类事实表比较少见。

2.维度表

维度,顾名思义,业务过程的发生或分析角度。比如从颜色、尺寸的角度来比较手机的外观,从cpu、内存等较比比较手机性能维。维度表一般为单一主键,在ER模型中,实体为客观存在的事物,会带有自己的 描述性属性,属性一般为文本性、描述性的,这些描述被称为维度。 比如商品,单一主键:商品ID,属性包括产地、颜色、材质、尺寸、单价等, 但并非属性一定是文本,比如单价、尺寸,均为数值型描述性的,日常主要的维度抽象包括:时间维度表、地理区域维度表等

案例:某电商平台,经常需要对订单进行分析,以某宝的购物订单为例,以维度建 模的方式设计该模型 涉及到事实表为订单表、订单明细表,维度包括商品维度、用户维度、商家维度、区域维 度、时间维度 商品维度:商品ID、商品名称、商品种类、单价、产地等 用户维度:用户ID、姓名、性别、年龄、常住地、职业、学历等 时间维度:日期ID、日期、周几、上/中/下旬、是否周末、是否假期等

维度分为:

(1)退化维度(DegenerateDimension)

在维度类型中,有一种重要的维度称作为退化维度,亦维度退化一说。这种维度指的是直接把一些简单的维度放在事实表中。退化维度是维度建模领域中的一个非常重要的概念,它对理解维度建模有着非常重要的作用,退化维度一般在分析中可以用来做分组使用。

(2)缓慢变化维(Slowly Changing Dimensions)

维度的属性并不是始终不变的,它会随着时间的流逝发生缓慢的变化,这种随时间发生变化的维度我们一般称之为缓慢变化维(SCD)。比如员工表中的部门维度,员工的所在部门有可能两年后调整一次。

3.维度建模模型的分类

维度建模按数据组织类型划分可分为星型模型、雪花模型、星座模型。

星型模型:星型架构是一种非正规化的结构,多维数据集的每一个维度都直接与事实表相连接,不存在渐变维度,所以数据有一定的冗余。

image.png

雪花型模型:在星型模型的基础上,维度表上又关联了其他维度表。这种模型维护成本高,性能方面也较差,所以一般不建议使用。尤其是基于hadoop体系构建数仓,减少join就是减少shuffle,性能差距会很大。

image.png

所以由上可以看出:
(1)星型模型和雪花模型主要区别就是对维度表的拆分
(2)对于雪花模型,维度表的涉及更加规范,一般符合3NF,有效降低数据冗余,维度表之间不会相互关联
(3)星型模型,一般采用降维的操作,反规范化,不符合3NF,利用冗余来避免模型过于复杂,提高易用性和分析效率,效率相对较高。

星座模型:是对星型模型的扩展延伸,多张事实表共享维度表。数仓模型建设后期,大部分维度建模都是星座模型。

4.维度建模步骤

维度建模步骤:选择业务过程->声明粒度->确定维度->确定事实。旨在重点解决数据粒度、维度设计和事实表设计问题。

image.png 声明粒度,为业务最小活动单元或不同维度组合。以共同粒度从多个组织业务过程合并度量的事实表称为合并事实表,需要注意的是,来自多个业务过程的事实合并到合并事实表时,它们必须具有同样等级的粒度。

1、选择业务过程

  • 业务过程是通常表示的是业务执行的活动,与之相关的维度描述和每个业务过程事件关联的描述性环境。
  • 通常由某个操作型系统支持,例如:订单系统。
  • 业务过程建立或获取关键性能度量。
  • 一系列过程产生一系列事实表。

2、声明粒度

  • 粒度传递的是与事实表度量有关的细节级别。
  • 精确定义某个事实表的每一行表示什么。
  • 对事实表的粒度要达成共识。

3、确认维度

  • 健壮的维度集合来粉饰事实表。
  • 维度表示承担每个度量环境中所有可能的单值描述符。

4、确认事实

  • 不同粒度的事实必须放在不同的事实表中。
  • 事实表的设计完全依赖物理活动,不受最终报表的影响。
  • 事实表通过外健关联与之相关的维度。
  • 查询操作主要是基于事实表开展计算和聚合。

其中粒度是非常重要的,粒度用于确定事实表的行表示什么,建议从关注原子级别的粒度数据开始设计,因为原子粒度能够承受无法预估的用户查询,而且原子数据可以以各种可能的方式进行上卷,而一旦选择了高粒度,则无法满足用户下钻细节的需求。

事实是整个维度建模的核心,其中雪花模型或者星型模型都是基于一张事实表通过外健关联维表进行扩展,生成一份能够支撑可预知查询需求的模型宽表,而且最后的查询也是落在事实表中进行。

三. DW/BI架构

image.png 首先对ETL得到的数据进行ER建模,关系建模,得到一个规范化的公司层面的数据仓库模式。然后用这个中心仓数据库为公司各部门建立基于维度建模的数据集市。

而维度建模都集中在各个DM层里面,也就是针对具体的业务线或者主题域,这样紧紧围绕着业务模型,可以直观的反映出业务模型中的业务问题。

至于DW层如何进行切分,是根据具体的业务需求和公司场景自己去定义,一般来说需要:

1、分层是解决数据流向和快速支撑业务的目的;

2、必须按照主题域和业务域进行贯穿;

3、层级之间不可逆向依赖。

4、如果依赖ODS层数据可以完成数据支撑,那么业务方直接使用落地层这也有利于快速、低成本地进行一些数据方面的探索和尝试。

5、确定分层规范后,后续最好都遵循这个架构,约定成俗即可;

6、血缘关系、数据依赖、数据字典、数据命名规范等配套先行;

DW 内的分层没有最正确的,只有最适合你的。

宽表的误区

在数仓层开始引入了宽表。所谓宽表,迄今为止并没有一个明确的定义。通常做法是把很多的维度、事实上卷或者下钻之后关联到某一个事实表中,形成一张既包含了大量维度又包含了相关事实的表。

宽表的使用,有其一定的便利性。使用方不需要再去考虑跟维度表的关联,也不需要了解维度表和事实表是什么东西。

但是随着业务的增长,我们始终无法预见性地设计和定义宽表究竟该冗余多少维度,也无法清晰地定义出宽表冗余维度的底线在哪里。

一个可能存在的情况是,为了满足使用上的需求,要不断地将维表中已经存在的列增加到宽表中。这直接导致了宽表的表结构频繁发生变动。

目前我们所采用的做法是:

1、根据主题域和业务域,将某个业务的所有节点梳理清楚;

2、将关键节点的数据作为事实表依据,然后横向扩充其他事实表上卷数据(包含一些统计指标),同时纵向的添加该节点上一些主键对应的维度;

3、宽表的涉及不依赖具体的业务需求而是根据整体业务线相匹配;

4、尽量用维度建模代替宽表;

为什么说尽量用维度建模代替宽表,就算字段和数据会冗余,维度建模的方式也会表全量数据的宽表模式较好,原因:

1、维度建模是以某一个既定的事实为依据,既然是事实表,那么这块的业务如果不变动的情况下,事实表的粒度基本不会改变;

2、事实表和维度表解耦,维度表的变更事实表基本不会影响,结果表也只需要回刷一下数据流程即可;

3、新增维度完全可以按照星型模型或者雪花模型动态添加新维度;

4、维度模型可以作为宽表的基础,一旦确定全部的数据流程,可以通过维度模型再生成对应宽表进行快速的业务支撑;

分层的误区

数仓层内部的划分不是为了分层而分层,分层是为了解决 ETL 任务及工作流的组织、数据的流向、读写权限的控制、不同需求的满足等各类问题。

业界较为通行的做法将整个数仓层又划分成了 dwd、dwb、dws、dim、mid 等等很多层。然而我们却始终说不清楚这几层之间清晰的界限是什么,或者说我们能说清楚它们之间的界限,复杂的业务场景却令我们无法真正落地执行。

image.png 源事务:业务库或者日志等各个方面的数据源,一般不维护历史信息。

ETL:目的是构建和加载数据到展现区的目标维度模型中,划分维度和事实。

模型:围绕业务过程度量事件进行构建,为满足用户无法预估的需求,必须包含详细的原子数据。

为避免数据的冗余存储造成的浪费和低效,并方便多业务部门查询方便以及同一指标的数据准确性和业务的扩展性,一般采取以下的架构模式

image.png

四. 数仓分层

数据仓库建设过程中一个重要的概念-数仓分层。分层是数据仓库解决方案中,数据架构设计的一种数据逻辑结构 ,通过分层理念建立的数据仓库,它的可扩展性非常好,这样设计出来的模型架构,可以任意地增减、替换数据仓库中的各个组成部分。通俗来说就是将不同整合粒度的数据划分到相应的层级中

数据仓库分层的好处:

用空间换时间:通过数据预处理提高效率,通过大量的预处理可以提升应用系统的用户体验(效率),相应的数据仓库会存储大量冗余的数据.

增强可扩展性:方便以后业务的变更。如果不分层的话,当源业务系统的业务规则发生变化整个数据仓库需要重建,这样将会影响整个数据清洗过程,工作量巨大。

简化清洗过程:通过分层管理来实现分步完成工作,简化数据清洗的过程,使每一层处理逻辑变得更简单。因为把原来一步的工作分到了多个步骤去完成,相当于把一个复杂的工作拆成了多个简单的工作,把一个大的黑盒变成了一个白盒,每一层的处理逻辑都相对简单和容易理解,这样我们比较容易保证每一个步骤的正确性,当数据发生错误的时候,往往我们只需要局部调整某个步骤即可。

同样以阿里数据仓库分层为例 image.png

其他比较常用的分层方式:
1、ODS原始层是存放原始数据,主要是埋点数据(日志数据)和业务操作数据(binlong),数据源主要是Mysql、HDFS、Kafka等

2、DW中间层主要存放ETL和主题汇总之后的中间层数据,这块又分为:

  • DWD:事实表(data warehouse detail) 数据仓库明细表,以业务过程作为建模驱动,基于每个具体的业务过程特点,构建最细粒度的明细层事实表。
  • DWS:事实表 (data warehouse summary) 数据仓库轻度汇总层,按照各个业务域进行轻度汇总成分析某一个主题域的服务数据,一般是宽表。
  • DIM:维度表,公共维度层,基于维度建模理念思想,建立整个业务过程的一致性维度,主要使用 MySQL、Hbase、Redis 三种存储引擎,对于维表数据比较少的情况可以使用 MySQL,对于单条数据大小比较小,查询 QPS 比较高的情况,可以使用 Redis 存储,降低机器内存资源占用,对于数据量比较大,对维表数据变化不是特别敏感的场景,可以使用HBase 存储。

3、DM数据集市层,以数据域+业务域的理念建设公共汇总层,对于DM层比较复杂,需要综合考虑对于数据落地的要求以及具体的查询引擎来选择不同的存储方式,分为轻度汇总层和高度汇总层。

  • 轻度汇总层以宽表的形式存在,主要是针对业务域进行快速方便的查询;
  • 高度汇总层由明细数据层或轻度汇总层通过聚合计算后写入到存储引擎中,产出一部分实时数据指标需求,灵活性比较差,主要做大屏展现。

4、理论上上面还一ODS层,主要是通过这几层之后,生成轻度或者高度汇总的数据,然后根据业务域进行接口封装提供给上层使用。

数据域

数据仓库存放了企业多个业务或者产品的数据,虽然可以根据抽象粒度进行分层,但是我们仍然需要标识业务类型和研究对象,就出现了业务域和主题域。业务域顾名思义就是描述产生此数据的业务,如:短信业务、二手车业务、金融业务、租房业务等,而主题域可以理解为研究的主体,比如:用户、商品、广告等。通过将两者组合来分别数据模型存储的信息内容。我们在ods之上的dw层,需要根据数据域(业务域和主题域),建不同的明细表。

五. 为什么选择维度建模

适配大数据的处理方式

维度模型的非强范式的,可以更好的利用大数据处理框架的处理能力,避免范式操作的过多关联操作,可以实现高度的并行化。
数据仓库大多数时候是比较适合使用星型模型构建底层数据Hive表,通过大量的冗余来提升查询效率,星型模型对OLAP的分析引擎支持比较友好,这一点在Kylin中比较能体现。
雪花模型在关系型数据库中如MySQL,Oracle中非常常见,尤其像电商的数据库表。

自下而上的建设现状

表已经存在,业务已经开发完毕,需求直接提过来了,这几乎是一个普遍现状,因为很少有公司会提前成立数据部门,让数据部门跟随着业务从头开始一直成长,都是当业务发展到一定的阶段了,想通过数据来提高公司的运营效果

简单的模型 使用简单

这个模型相对来说是比较简单的,简单主要体现在两个方面

  1. 维度建模非常直观,紧紧围绕着业务模型,可以直观的反映出业务模型中的业务问题。不需要经过特别的抽象处理,即可以完成维度建模。这一点也是维度建模的优势。
  2. 星型结构的实现不用考虑很多正规化的因素,设计与实现都比较简单。

分层和建模的关系

明细层的范式模型

明细层采用传统的三范式关系模型。这一层次的数据模型要将业务过程描述清楚,将源数据(即业务系统)中隐含的、有歧义的概念进行清晰化,如活跃用户、VIP用户等。该层次的数据模型追求的目标是灵活地表达业务过程,要保证数据一致性、唯一性、正确性,以尽量少的代价与源数据保持数据同步,同时该层次的数据模型不建议开给不懂技术的业务人员直接使用,因此,采用关系型的三范式模型是最佳的选择。

集市层的维度模型

集市层是按照业务主题、分主题构建出来的、面向特定部门或人员的数据集合,该层次的数据模型会开放给业务人员使用,进行数据挖掘及业务分析。由于业务员多数不懂数据库技术,缺少将业务需求转换为关系型数据结构的逻辑思维,更写不出复杂的SQL语句,因此,越简单的数据模型,越能被他们所接受,因此,这个层次所构建出来的数据模型,要按照业务过程进行组织,每个事实表代表一个独立的业务过程,事实表之间不存在直接的依赖关系,这样业务人员可以很容易地将分析需求对应到事实表上,利用工具或手工写出简单的SQL,将统计数据提取出来进行分析。

模型实现

模型的实现主要指的是在维度建模过程中,需要对维度表和事实表进行关联设计,而这里我们对维度表的设计,就决定了我们最终与事实表关联的之后的形态。也就是说我们可以根据事实表和维度表的关系,又可将常见的模型分为星型模型和雪花型模型

星型模型和雪花模型的主要区别在于对维度表的拆分对于雪花模型,维度表的设计更加规范,一般符合3NF;而星型模型,一般采用降维的操作,利用冗余来避免模型过于复杂,提高易用性和分析效率

六.建模方法应用场景对比:

  • 星型模型的设计方式主要带来的好处是能够提升查询效率,因为生成的事实表已经经过预处理,主要的数据都在事实表里面,所以只要扫描事实表就能够进行大量的查询,而不必进行大量的join,其次维表数据一般比较少,在join可直接放入内存进行join以提升效率,除此之外,星型模型的事实表可读性比较好,不用关联多个表就能获取大部分核心信息,设计维护相对比较简答。
  • 雪花模型的设计方式是比较符合数据库范式的理念,设计方式比较正规,数据冗余少,但在查询的时候可能需要join多张表从而导致查询效率下降,此外规范化操作在后期维护比较复杂。
  • 范式建模是从关系型数据库的角度出发,结合了业务系统的数据模型,能够比较方便的实现数据仓库的建模,易于维护,高度集成;由于建模方法限定在关系型数据库之上,在某些时候反而限制了整个数据仓库模型的灵活性,性能等,特别是考虑到数据仓库的底层数据向数据集市的数据进行汇总时,需要进行一定的变通才能满足相应的需求,结构死板,部署周期较长,主要解决关系型数据库得数据存储,利用的一种技术层面上的方法。
  • 实体建模法,能够很轻松的实现业务模型的划分,因此,在业务建模阶段和领域概念建模阶段,实体建模法有着广泛的应用。再没有现成的行业模型的情况下,我们可以采用实体建模的方法,和客户一起理清整个业务的模型,进行领域概念模型的划分,抽象出具体的业务概念,但实体建模法也有着自己先天的缺陷,由于实体说明法只是一种抽象客观世界的方法,因此,注定了该建模方法只能局限在业务建模和领域概念建模阶段。

选型建议:

  • 在关系型数据库中的建模方法,大部分采用的是第三范式建模法;
  • 维度建模星型架构是比较常见的。因为我们在实际项目中,往往最关注的是查询性能问题,至于磁盘空间一般都不是问题。当然,在维度表数据量极大,需要节省存储空间的情况下,或者是业务逻辑比较复杂、必须要体现清晰的层次概念情况下,可以使用雪花型维度。在复合式的数据仓库架构中,操作型或事务型系统的数据源,通过ETL抽取转换和加载到数据仓库的ODS层,然后通过ODS的数据,利用范式建模方法,建设原子数据的数据仓库EDW,然后基于EDW,利用维度建模方法建设数据集市;
  • 至于实体建模很少使用,也仅仅局限于业务/领域建模,到了逻辑建模阶段和物理建模阶段,则是范式建模和维度建模发挥长处的阶段。
参考文章

zhuanlan.zhihu.com/p/137454121
blog.csdn.net/qq_26442553…
zhuanlan.zhihu.com/p/336365950
cloud.tencent.com/developer/a…
xie.infoq.cn/article/65a…