第4章 维度建模理论之维度表
4.1 维度表概述
维度表是维度建模的基础和灵魂。前文提到,事实表紧紧围绕业务过程进行设计,而维度表则围绕业务过程所处的环境进行设计。维度表主要包含一个主键和各种维度字段,维度字段称为维度属性。
4.2 维度表设计步骤
1)确定维度(表)
在设计事实表时,已经确定了与每个事实表相关的维度,理论上每个相关维度均需对应一张维度表。需要注意到,可能存在多个事实表与同一个维度都相关的情况,这种情况需保证维度的唯一性,即只创建一张维度表。另外,如果某些维度表的维度属性很少,例如只有一个**名称,则可不创建该维度表,而把该表的维度属性直接增加到与之相关的事实表中,这个操作称为维度退化。
2)确定主维表和相关维表
此处的主维表和相关维表均指业务系统中与某维度相关的表。例如业务系统中与课程相关的表有course_info,chapter_info,base_subject_info,base_category_info,video_info等,其中course_info就称为课程维度的主维表,其余表称为课程维度的相关维表。维度表的粒度通常与主维表相同。
3)确定维度属性
确定维度属性即确定维度表字段。维度属性主要来自于业务系统中与该维度对应的主维表和相关维表。维度属性可直接从主维表或相关维表中选择,也可通过进一步加工得到。
确定维度属性时,需要遵循以下要求:
(1)尽可能生成丰富的维度属性
维度属性是后续做分析统计时的查询约束条件、分组字段的基本来源,是数据易用性的关键。维度属性的丰富程度直接影响到数据模型能够支持的指标的丰富程度。
(2)尽量不使用编码,而使用明确的文字说明,一般可以编码和文字共存。
(3)尽量沉淀出通用的维度属性
有些维度属性的获取需要进行比较复杂的逻辑处理,例如需要通过多个字段拼接得到。为避免后续每次使用时的重复处理,可将这些维度属性沉淀到维度表中。
4.3 维度设计要点
4.3.1 规范化与反规范化
规范化是指使用一系列范式设计数据库的过程,其目的是减少数据冗余,增强数据的一致性。通常情况下,规范化之后,一张表的字段会拆分到多张表。
反规范化是指将多张表的数据冗余到一张表,其目的是减少join操作,提高查询性能。
在设计维度表时,如果对其进行规范化,得到的维度模型称为雪花模型,如果对其进行反规范化,得到的模型称为星型模型。

数据仓库系统的主要目的是用于数据分析和统计,所以是否方便用户进行统计分析决定了模型的优劣。采用雪花模型,用户在统计分析的过程中需要大量的关联操作,使用复杂度高,同时查询性能很差,而采用星型模型,则方便、易用且性能好。所以出于易用性和性能的考虑,维度表一般是很不规范化的。
4.3.2 维度变化
维度属性通常不是静态的,而是会随时间变化的,数据仓库的一个重要特点就是反映历史的变化,所以如何保存维度的历史状态是维度设计的重要工作之一。保存维度数据的历史状态,通常有以下两种做法,分别是全量快照表和拉链表。
1)全量快照表
离线数据仓库的计算周期通常为每天一次,所以可以每天保存一份全量的维度数据。这种方式的优点和缺点都很明显。
优点是简单而有效,开发和维护成本低,且方便理解和使用。
缺点是浪费存储空间,尤其是当数据的变化比例比较低时。
2)拉链表
拉链表的意义就在于能够更加高效的保存维度信息的历史状态。
(1)什么是拉链表

(2)为什么要做拉链表

(3)如何使用拉链表

4.3.3 多值维度
如果事实表中一条记录在某个维度表中有多条记录与之对应,称为多值维度。例如,下单事实表中的一条记录为一个订单,一个订单可能包含多个课程,所以课程维度表中就可能有多条数据与之对应。
针对这种情况,通常采用以下两种方案解决。
第一种:降低事实表的粒度,例如将订单事实表的粒度由一个订单降低为一个订单中的一门课程。
第二种:在事实表中采用多字段保存多个维度值,每个字段保存一个维度id。这种方案只适用于多值维度个数固定的情况。
建议尽量采用第一种方案解决多值维度问题。
4.3.4 多值属性
维表中的某个属性同时有多个值,称之为“多值属性”,例如课程维度的课程类别,每个课程均有多个属性值。
针对这种情况,通常有可以采用以下两种方案。
第一种:将多值属性放到一个字段,该字段内容为key1:value1,key2:value2或者 value1,value2的形式。如课程类别属性,一个课程可以属于编程技术、后端开发等多个类别。
第二种:将多值属性放到多个字段,每个字段对应一个属性。这种方案只适用于多值属性个数固定的情况。
第5章 数据仓库设计
5.1 数据仓库分层规划
优秀可靠的数仓体系,需要良好的数据分层结构。合理的分层,能够使数据体系更加清晰,使复杂问题得以简化。以下是该项目的分层规划。

5.2 数据仓库构建流程
以下是构建数据仓库的完整流程。

5.2.1 数据调研
数据调研重点要做两项工作,分别是业务调研和需求分析。这两项工作做的是否充分,直接影响着数据仓库的质量。
1)业务调研
业务调研的主要目标是熟悉业务流程、熟悉业务数据。
熟悉业务流程要求做到,明确每个业务的具体流程,需要将该业务所包含的每个业务过程一一列举出来。
熟悉业务数据要求做到,将数据(包括埋点日志和业务数据表)与业务过程对应起来,明确每个业务过程会对哪些表的数据产生影响,以及产生什么影响。产生的影响,需要具体到,是新增一条数据,还是修改一条数据,并且需要明确新增的内容或者是修改的逻辑。
下面以在线教育中的交易业务为例进行演示,交易业务涉及到的业务过程有用户试听、用户下单、用户支付,具体流程如下图。

2)需求分析
典型的需求指标如,最近一天各省份 Java 学科订单总额。
分析需求时,需要明确需求所需的业务过程及维度,例如该需求所需的业务过程就是用户下单,所需的维度有日期,省份,科目。
3)总结
做完业务分析和需求分析之后,要保证每个需求都能找到与之对应的业务过程及维度。若现有数据无法满足需求,则需要和业务方进行沟通,例如某个页面需要新增某个行为的埋点。
5.2.2 明确数据域
数据仓库模型设计除横向的分层外,通常也需要根据业务情况进行纵向划分数据域。
划分数据域的意义是便于数据的管理和应用。
通常可以根据业务过程或者部门进行划分,本项目根据业务过程进行划分,需要注意的是一个业务过程只能属于一个数据域。
下面是本数仓项目所需的所有业务过程及数据域划分详情。
|
数据域 |
业务过程 |
|
交易域 |
加购、下单、支付成功 |
|
流量域 |
页面浏览、启动应用、动作、曝光、错误 |
|
用户域 |
注册、登录 |
|
互动域 |
收藏、评价 |
|
考试域 |
考试 |
|
学习域 |
观看视频 |
5.2.3 构建业务总线矩阵
业务总线矩阵中包含维度模型所需的所有事实(业务过程)以及维度,以及各业务过程与各维度的关系。矩阵的行是一个个业务过程,矩阵的列是一个个的维度,行列的交点表示业务过程与维度的关系。

一个业务过程对应维度模型中一张事务型事实表,一个维度则对应维度模型中的一张维度表。所以构建业务总线矩阵的过程就是设计维度模型的过程。但是需要注意的是,总线矩阵中通常只包含事务型事实表,另外两种类型的事实表需单独设计。
按照事务型事实表的设计流程,选择业务过程à声明粒度à确认维度à确认事实,得到的最终的业务总线矩阵见以下表格。
| 数据域 | 业务过程 | 粒度 | 维度 | 度量 | |||||||||
| 用户 | 地区 | 时间 | 课程 | 章节 | 试卷 | 问题 | 视频 | 来源 | 设备 | ||||
| 交易域 | 加购物车 | 一次加购物车的操作 | √ | √ | √ | 加购时价格 | |||||||
| 下单 | 一个订单中的一门课程 | √ | √ | √ | √ | √ | 下单原始金额/下单最终金额/优惠券减免金额 | ||||||
| 支付成功 | 一个订单中一门课程的支付成功操作 | √ | √ | √ | √ | 支付原始金额/支付最终金额/优惠券减免金额 | |||||||
| 流量域 | 页面浏览 | 一次页面浏览记录 | √ | √ | √ | √ | √ | 浏览时长 | |||||
| 动作 | 一次动作记录 | √ | √ | √ | √ | √ | √ | 无事实(次数1) | |||||
| 曝光 | 一次曝光记录 | √ | √ | √ | √ | √ | √ | 无事实(次数1) | |||||
| 启动应用 | 一次启动记录 | √ | √ | √ | √ | √ | 无事实(次数1) | ||||||
| 错误 | 一次错误记录 | √ | √ | √ | √ | √ | 无事实(次数1) | ||||||
| 用户域 | 注册 | 一次注册操作 | √ | √ | 无事实(次数1) | ||||||||
| 登录 | 一次登录操作 | √ | √ | √ | √ | √ | 无事实(次数1) | ||||||
| 互动域 | 收藏商品 | 一次收藏商品操作 | √ | √ | √ | 无事实(次数1) | |||||||
| 评价 | 一个用户对课程中一个章节的一次评价 | √ | √ | √ | √ | 无事实(次数1) | |||||||
| 评价 | 一个用户对一门课程的一次整体评价 | √ | √ | √ | 无事实(次数1) | ||||||||
| 考试 | 考试 | 一个用户的一次答卷记录 | √ | √ | √ | 得分/时长 | |||||||
| 考试 | 一个用户的一次答题记录 | √ | √ | √ | √ | 得分 | |||||||
| 学习 | 观看视频 | 一个会话的视频播放记录 | √ | √ | √ | √ | √ | √ | √ | 播放时长 | |||
后续的DWD层以及DIM层的搭建需参考业务总线矩阵。
5.2.4 明确统计指标
明确统计指标具体的工作是,深入分析需求,构建指标体系。构建指标体系的主要意义就是指标定义标准化。所有指标的定义,都必须遵循同一套标准,这样能有效的避免指标定义存在歧义,指标定义重复等问题。
1)指标体系相关概念
(1)原子指标
原子指标基于某一业务过程的度量值,是业务定义中不可再拆解的指标,原子指标的核心功能就是对指标的聚合逻辑进行了定义。我们可以得出结论,原子指标包含三要素,分别是业务过程、度量值和聚合逻辑。
例如订单总额就是一个典型的原子指标,其中的业务过程为用户下单、度量值为订单金额,聚合逻辑为sum()求和。需要注意的是原子指标只是用来辅助定义指标一个概念,通常不会对应有实际统计需求与之对应。
(2)派生指标
派生指标基于原子指标,其与原子指标的关系如下图所示。

与原子指标不同,派生指标通常会对应实际的统计需求。请从图中的例子中,体会指标定义标准化的含义。
(3)衍生指标
衍生指标是在一个或多个派生指标的基础上,通过各种逻辑运算复合而成的。例如比率、比例等类型的指标。衍生指标也会对应实际的统计需求。
2)指标体系对于数仓建模的意义
通过上述两个具体的案例可以看出,绝大多数的统计需求,都可以使用原子指标、派生指标以及衍生指标这套标准去定义。同时能够发现这些统计需求都直接的或间接的对应一个或者是多个派生指标。
当统计需求足够多时,必然会出现部分统计需求对应的派生指标相同的情况。这种情况下,我们就可以考虑将这些公共的派生指标保存下来,这样做的主要目的就是减少重复计算,提高数据的复用性。
这些公共的派生指标统一保存在数据仓库的DWS层。因此DWS层设计,就可以参考我们根据现有的统计需求整理出的派生指标。
5.2.4 维度模型设计
维度模型的设计参照上述得到的业务总线矩阵即可。事实表存储在DWD层,维度表存储在DIM层。
5.2.5 汇总模型设计
汇总模型的设计参考上述整理出的指标体系(主要是派生指标)即可。汇总表与派生指标的对应关系是,一张汇总表通常包含业务过程相同、统计周期相同、统计粒度相同的多个派生指标。请思考:汇总表与事实表的对应关系是?




