离线数仓(五)【数据仓库建模】(1)

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB PostgreSQL 版,企业版 4核16GB
推荐场景:
HTAP混合负载
云原生数据仓库AnalyticDB MySQL版,8核32GB 100GB 1个月
简介: 离线数仓(五)【数据仓库建模】

前言

       今天开始正式数据仓库的内容了, 前面我们把生产数据 , 数据上传到 HDFS , Kafka 的通道都已经搭建完毕了, 数据也就正式进入数据仓库了, 解下来的数仓建模是重中之重 , 是将来吃饭的家伙 ! 以及 Hive SQL 必须熟练到像喝水一样 !

1章 数据仓库概述

1.1 数据仓库概念

       数据仓库 (dataware,简称 DW) 是一个为数据分析而设计的企业级数据管理系统。数据仓库可集中、整合多个信息源的大量数据,借助数据仓库的分析能力,企业可从数据中获得宝贵的信息进而改进决策。同时,随着时间的推移,数据仓库中积累的大量历史数据对于数据科学家和业务分析师也是十分宝贵的。

       数据仓库必须具备存储 , 管理 , 分析和计算的能力 !

       数据仓库并不是数据的最终目的地 , 而是提供给数据仓库下游的应用 !

1.2 数据仓库核心架构

       Hive 一般都是用来作为我们数据仓库的主体 , 因为它具备数仓必备的存储 (底层是 HDFS , 所以可以存储海量数据) , 管理 (Hive 可以将我们 HDFS 中的数据映射成一张张的二维表)  以及分析计算 (Hive 支持通过 Hive SQL 来对二维表进行分析查询, 它的引擎可以是 MR / Tez / Spark)

       业务系统: 就是企业当中支撑公司核心业务的系统 , 比如电商公司的核心就是电商业务系统 , 那么它产生的大量的业务数据(比如订单数据,用户信息数据等)和用户行为日志数据(比如点击某个按钮,收藏) 对我们数据的分析都是非常有意义的,都需要采集到数仓当中 .

       DataX 是一个基于查询的全量采集工具 ( select * ) , 而 Maxwell 是基于 binlog 的一个增量数据采集工具 .它们都是业务数据采集工具 (从 MySQL 这种关系型数据库采集到 HDFS) , 而用户行为数据我们用的一般是 Flume .

       数据采集到数仓之后就需要把这些 HDFS 文件映射成一张张二维表了 (通过 load 语句),  之后我们就可以开始进行数仓建模了 . 所谓的数据建模就是对数据进行更加合理高效的存储整理 , 最终我们的数据就被分为多层 , 每层存储的都是一张张二维表 , 而且每一层都有自己的处理逻辑 , 每一层都是从上一层计算的结果 .

       整个数仓的重点就是 Hive 了 , 我们的主要工作其实就是数仓的建模和写 SQL  . 关于建模我们要知道每一层的每一张表有哪些字段 , 每一行每一列分别代表什么含义 . SQL 是对数据进行处理 , 以便发送给下一层 .

       Hive 数仓中不同层之间需要执行不同的 SQL , 而且必须等待上一层执行完才能执行 , 这就需要一个调度框架来协调任务的执行了 ( linux 的 crontab 命令并不能满足这个需求 , 因为 crontab 并不能确定上一个任务是否执行完毕 , 估算可能会出现误差 ) 这里我们用的是 Dolphin Scheduler 这是一个国产的工作流程定时调度器 (工作流程是由一个个的工作单元组成的 , 就比如我们这里每一层的 SQL )

       这里强调最重要的就是数仓建模和 SQL , 菜就多练 !

第2章 数据仓库建模概述

2.1 数据仓库建模的意义

       如果把数据看作图书馆里的书,我们希望看到它们在书架上分门别类地放置;如果把数据看作城市的建筑,我们希望城市规划布局合理;如果把数据看作电脑文件和文件夹,我们希望按照自己的习惯有很好的文件夹组织方式,而不是糟糕混乱的桌面,经常为找一个文件而不知所措。

       数据模型就是数据组织和存储方法,它强调从业务、数据存取和使用角度合理存储数据。只有将数据有序的组织和存储起来之后,数据才能得到高性能、低成本、高效率、高质量的使用。

  • 高性能:良好的数据模型能够帮助我们快速查询所需要的数据。(比如说使用宽表来减少作业中多表 join 的计算开销)
  • 低成本:良好的数据模型能减少重复计算,实现计算结果的复用,降低计算成本。
  • 高效率:良好的数据模型能极大的改善用户(数仓的用户: 比如下游的应用)使用数据的体验,提高使用数据的效率。
  • 高质量:良好的数据模型能改善数据统计口径 (防止歧义) 的混乱,减少计算错误的可能性。

2.2 数据仓库建模方法论

目前数仓用的更多的是下面的维度模型,至于 ER 模型更多的是在关系型数据库中用的比较多 。

2.2.1 ER模型 (了解)

       数仓库之父Bill Inmon ( 比尔沂蒙 )提出的建模方法是从全企业的高度,用实体关系(Entity Relationship,ER)模型来描述企业业务,并用规范化 ( 数据库规范化 , 范式等级一般为第三范式 ) 的方式表示出来,在范式理论上符合3NF。      

       比如说学生管理系统 , 对于学生和班级这两个实体的关系,一个学生一般对应一个班级,但是一个班级对应多个学生,所以我们就可以在学生表中使用外键来关联班级信息.

       同样 , 比如学生表和课程表 , 一个学生可能有多门课程 , 一们课程也有多个学生 , 这种关系用外键是实现不了的 , 我们可以在两张表中间加入一张选课表 , 表中主要就俩字段 学生id和课程id 就足以说明了两者之间的关系了 。

1)实体关系模型

       实体关系模型将复杂的数据抽象为两个概念——实体和关系。实体表示一个对象,例如学生、班级,关系是指两个实体之间的关系,例如学生和班级之间的从属关系。

2)数据库规范化

       数据库规范化是使用一系列范式 (normal form) 设计数据库(通常是关系型数据库)的过程,其目的是减少数据冗余 (数据重复 , 比如有多张表都存储了同一个字段,比如一张表的一个字段值有重复 ; 因为数据冗余会浪费存储空间) ,增强数据的一致性 (正因为存在数据冗余 , 同一个字段被多次存储在多张表中 , 如果一张表进行了修改但是别的表没有修改 , 这就造成了数据的不一致性问题)

       这一系列范式就是指在设计关系型数据库时,需要遵从的不同的规范。关系型数据库的范式一共有六种,分别是第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF)。遵循的范式级别越高,数据冗余性就越低。

3)三范式

       范式必须按顺序去遵守 , 比如遵循了第一范式 , 才能遵循第二范式 , 遵循了第二范式才能遵循第三范式 ... 但是遵循范式并不是越多越好 , 范式级别越高 , 我们的表就被拆分的越细 , 我们的关系模型就变得复杂 , 而且我们稍微复杂一点的查询可能就需要 join 了 . 一般我们都会做一个折中的取舍 , 选择第三范式 , 甚至是第二范式 .

(1)函数依赖

完全函数依赖:

       比如 f(x,y) = z ; 我们必须知道三个未知数 x,y,z 中的两个值才能知道另一个的值 . 对应到表中就比如我们必须通过 (学号,课程名) 才能得到该学生的分数 , 缺一不可 .

部分函数依赖:

       比如我们可以通过 (学号 , 课程名) 来得到学生的姓名 , 但是要知道学生的姓名其实并不需要得到课程名 , 这里的 姓名就是部分依赖于  (学号 , 课程名) 的 .

传递函数依赖:

       比如 f(x) = y , g(y) = z , 那么我们就可以通过知道 x 的值来得到 z .对应到表中就是我们可以通过学生的学号知道这个学生是哪个系的 , 然后通过系名就可以知道这个系的主任是谁 , 这里就是系主任传递函数依赖于学号.

(2)第一范式 (1NF)

核心原则: 属性不可切分 , 对应到表中就是字段不可切分

ID 订单 商家id 用户id
001 联想小新Pro15 * 5 xxx旗舰店 00001

这里上面的属性 "订单" 就不符合第一范式 , 因为它可以再拆分为:

第一范式非常简单 , 它并没有函数依赖 , 但是非常重要 , 因为它是所有范式的基础 .

(3)第二范式 (2NF)

核心原则: 不能存在 "部分函数依赖" , 对应到表中就是 "不能存在非主键字段部分函数依赖于主键字段"

       这里的主键是由 "学号" 和 "课名" 组成的联合主键 , 可以看到 , 这张表中冗余的部分: 姓名 , 系名和系主任都是部分依赖函数于联合主键字段中的学号的 , 而分数是完全依赖于这个联合主键的 .

       消除函数依赖实现第二范式的方式就是把这张表中完全依赖的部分单独拆出来:

       这样就既满足了第二范式 , 也解决了数据的冗余 . 但是我们还会发现 , 在第二张表中依然存在系名和系主任数据冗余的问题 , 这就需要我们来了解一下第三范式了 :

(4)第三范式 (3NF)

核心: 不能存在传递函数依赖 , 对应到我们的关系型数据库表中就是 , 不能存在非主键字段传递函数依赖于主键字段

        这里的学号可以推出系名 ,  然后系名可以推出系主任 , 所以这里存在系主任传递函数于学号( 主键 ) , 我们需要继续拆表:

下面我们看一个采用 Bill Inmon 倡导的建模方法(ER 模型) 构建的模型 :

       我们可以看到一张订单明细表现在被拆分成了十几张表 , 这种建模方法的出发点是整合数据,其目的是将整个企业的数据进行组合和合并,并进行规范处理,减少数据冗余性,保证数据的一致性。这种模型并不适合直接用于分析统计。

       假如我们要写一个查询实现统计出每个国家 2024 年的订单金额的总额 , 那么我们就需要对上面接近 10 张的表进行 join 操作 !

2.2.2 维度模型 (重点)

       数据仓库领域的另一位大师——Ralph Kimball倡导的建模方法为维度建模。维度模型将复杂的业务通过事实维度两个概念进行呈现。事实通常对应业务过程(行为),而维度通常对应业务过程发生时所处的环境(人时地)。

:业务过程可以概括为一个个不可拆分的行为事件,例如电商交易中的下单,取消订单,付款,退单等,都是业务过程。

       下图为一个典型的维度模型,其中位于中心的SalesOrder为事实表,其中保存的是下单这个业务过程的所有记录。位于周围每张表都是维度表,包括Date(日期),Customer(顾客),Product(产品),Location(地区)等,这些维度表就组成了每个订单发生时所处的环境,即何人、何时、在何地下单了何种产品。从图中可以看出,模型相对清晰、简洁。

       维度建模以数据分析作为出发点,为数据分析服务,因此它关注的重点是用户如何更快的完成需求分析以及如何实现较好的大规模复杂查询的响应性能

       但是维度模型的缺点也显而易见,那就是数据冗余(主要是维度表),数据冗余的问题主要就是存储浪费和数据一致性问题,对我们的 Hive 数仓来说根本不是问题,至于数据一致性,由于我们数仓的数据写进来后是不怎么会去修改的,所以数据一致性也不是问题。

第3章 维度建模理论之事实表

牢记:所有的事实表它的字段都是由 维度外键 和 度量指标 组成的!

3.1 事实表概述

       事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程(下单、退款、付款)来设计。其包含与该业务过程有关的维度引用(维度表外键)以及该业务过程的度量(通常是可累加的数字类型字段,用来量化业务过程的字段,比如用下单总金额或者下单的商品数量来量化下单这个业务过程)。

3.1.1 事实表特点

       事实表通常比较“细长”,即列较少,但行较多,且行的增速快。

3.1.2 事实表分类

       事实表有三种类型:分别是事务事实表周期快照事实表累积快照事实表,其中,事务事实表占据主要地位,也就是说事务事实表是常见的,但是周期快照事实表和累积快照事实表是可以不存在的。每种事实表都具有不同的特点和适用场景,下面逐个介绍。

3.2 事务型事实表(重点)

3.2.1 概述

       事务型事实表用来记录各业务过程,它保存的是各业务过程的原子操作事件,即最细粒度的操作事件。粒度是指事实表中一行数据所表达的业务细节程度比如订单信息表和订单明细表,订单信息表中每一行存储的是每个订单(包含多个商品)的数据,而订单明细表中每一行存储的是每个订单中的每个商品的信息。

       事务型事实表可用于分析与各业务过程相关的各项统计指标,由于其保存了最细粒度的记录,可以提供最大限度的灵活性,可以支持无法预期的各种细节层次的统计需求

3.2.2 设计流程

       设计事务事实表时一般可遵循以下四个步骤:选择业务过程→声明粒度→确认维度→确认事实

1)选择业务过程

       在业务系统中,挑选我们感兴趣的业务过程(也就是我们的需求),业务过程可以概括为一个个不可拆分的行为事件,例如电商交易中的下单,取消订单,付款,退单等,都是业务过程。通常情况下,一个业务过程对应一张事务型事实表

2)声明粒度(确定每行代表什么)

       业务过程确定后,需要为每个业务过程声明粒度。即精确定义每张事务型事实表的每行数据表示什么,应该尽可能选择最细粒度,以此来应各种细节程度的需求。

典型的粒度声明如下:

       订单事实表中一行数据表示的是一个订单中的一个商品项。

3)确定维度(确定维度外键)

       确定维度具体是指,确定与每张事务型事实表相关的维度有哪些。

       确定维度时应尽量多的选择与业务过程相关的环境信息。因为维度的丰富程度就决定了维度模型能够支持的指标丰富程度

4)确定事实(确定度量指标)

       此处的“事实”一词,指的是每个业务过程的度量值(通常是可累加的数字类型的值,例如:次数、个数、件数、金额等)

       经过上述四个步骤,事务型事实表就基本设计完成了。第一步选择业务过程可以确定有哪些事务型事实表,第二步可以确定每张事务型事实表的每行数据是什么,第三步可以确定每张事务型事实表的维度外键,第四步可以确定每张事务型事实表的度量值字段。

3.2.3 不足

       事务型事实表可以保存所有业务过程的最细粒度的操作事件,故理论上其可以支撑与各业务过程相关的各种统计粒度的需求。但对于某些特定类型的需求,其逻辑可能会比较复杂,或者效率会比较低下。例如:

1)存量型指标

       例如商品库存,账户余额等。此处以电商中的虚拟货币(淘金币、京豆)为例,虚拟货币业务包含的业务过程主要包括获取货币和使用货币,两个业务过程各自对应一张事务型事实表,一张存储所有的获取货币的原子操作事件,另一张存储所有使用货币的原子操作事件。

       假定现有一个需求,要求统计截至当日的各用户虚拟货币余额。由于获取货币和使用货币均会影响到余额,故需要对两张事务型事实表进行聚合,且需要区分两者对余额的影响(加或减),另外需要对两张表的全表数据聚合才能得到统计结果。

       可以看到,不论是从逻辑上还是效率上考虑(事务事实表非常大,做聚合操作比较耗时),这都不是一个好的方案。

2)多事务关联统计

       例如,现需要统计最近30天,用户下单到支付的时间间隔的平均值。统计思路应该是找到下单事务事实表和支付事务事实表,以订单id作为关联条件join得到下单时间和支付时间,过滤出最近30天的记录,然后按照订单id对两张事实表进行关联,之后用支付时间减去下单时间,然后再求平均值。

       逻辑上虽然并不复杂,但是其效率较低,应为下单事务事实表和支付事务事实表均为大表,大表 join 大表的操作应尽量避免。

       可以看到,在上述两种场景下事务型事实表的表现并不理想。下面要介绍的另外两种类型的事实表就是为了弥补事务型事实表的不足的。其中,周期型快照事实表就是用来解决存量型指标的,而累积型快照事实表就是用来解决多事务关联统计

3.3 周期型快照事实表

3.3.1 概述

       周期快照事实表以具有规律性的、可预见的时间间隔来记录事实,主要用于分析一些存量型(例如商品库存,账户余额)或者状态型(空气温度,行驶速度)指标

       对于商品库存、账户余额这些存量型指标,业务系统中(MySQL)通常就会计算并保存最新结果,所以定期同步一份全量数据到数据仓库,构建周期型快照事实表,就能轻松应对此类统计需求,而无需再对事务型事实表中大量的历史记录进行聚合了。

       周期快照表通常都是分区表,根据日期分区

       核心思想就是直接利用业务系统重现有的结果,而不是费时地去对事务事实表(大表)进行聚合

       对于空气温度、行驶速度这些状态型指标,由于它们的值往往是连续的,我们无法捕获其变动的原子事务操作(原子事务操作:比如下单买了几件商品花了多少钱),所以无法使用事务型事实表统计此类需求。而只能定期对其进行采样,构建周期型快照事实表(比如每隔 1 小时记录一下空气温度的变化值)。

3.3.2 设计流程

1)确定粒度(确定每行是什么,以及部分列代表什么)

       周期型快照事实表的粒度可由采样周期维度描述,故确定采样周期和维度后即可确定粒度。

       采样周期通常选择每日。

       维度可根据统计指标决定,例如指标为统计每个仓库中每种商品的库存,则可确定维度为仓库和商品。

       确定完采样周期和维度后,即可确定该表粒度为每日-仓库-商品(所以这个周期快照表的一行代表每天每个仓库每个商品的某个指标值,我们也就确定了除了度量指标的三个列:日期 + 仓库id + 商品id )。

2)确认事实

       事实也可根据统计指标决定,例如指标为统计每个仓库中每种商品的库存,则事实为商品库存。到这里我们也就确定了最后一个字段(度量指标):库存数量。

3.3.3 事实类型

       此处的事实类型是指度量值的类型,而非事实表的类型。事实(度量值)共分为三类,分别是可加事实半可加事实不可加事实

1)可加事实

       可加事实是指可以按照与事实表相关的所有维度进行累加,例如事务型事实表中的事实。

2)半可加事实

       半可加事实是指只能按照与事实表相关的一部分维度进行累加,例如周期型快照事实表中的事实。以上述各仓库中各商品的库存每天快照事实表为例,这张表中的库存事实可以按照仓库或者商品维度进行累加,但是不能按照时间维度进行累加,因为将每天的库存累加起来是没有任何意义的。

总结:事务型事实表中的事实都是可加事实,周期型快照事实表中的事实都是半可加事实!

3)不可加事实

       不可加事实是指完全不具备可加性,例如比率型事实(比如退货率=退货数/下单数,我们假如有一张表有两个字段:商品id,退货率;显然不管根据商品id这个维度还是退货率这个度量指标都是无法累加的)。不可加事实应尽量避免,所以通常需要转化为可加事实,例如比率可转化为分子和分母。

3.4 累积型快照事实表

3.4.1 概述

       累计快照事实表是基于一个业务流程(区别于业务过程,业务过程指的是一个业务的原子操作,而业务流程是由多个有关联的业务过程组成的)中的多个关键业务过程联合处理而构建的事实表,如交易流程中的下单、支付、发货、确认收货业务过程。

       累积型快照事实表通常具有多个日期字段,每个日期对应业务流程中的一个关键业务过程(里程碑)比如下面的 下单日期  -> 支付日期  -> 发货日期 -> 收货日期。

订单id

用户id

下单日期

支付日期

发货日期

确认收货日 期

订单金额

支付金额

1001

1234

2020-06-14

2020-06-15

2020-06-16

2020-06-17

1000

1000

维度外键(多个业务过程对应的维度外键):

订单id

用户id

下单日期

支付日期

发货日期

确认收货日 期

度量值(多个业务过程的度量值):

订单金额

支付金额

       累积型快照事实表主要用于分析业务过程(里程碑)之间的时间间隔等需求。例如前文提到的用户下单到支付的平均时间间隔,使用累积型快照事实表进行统计,就能避免两个事务事实表的关联操作,从而变得十分简单高效。

       这里的累积指的是这张表不是一次创建好的,比如用户下单,我们就可以从订单事务事实表中拿到下单日期和下单金额放到我们这张表中;过了一天用户支付,我们又可以从支付事务事实表中拿到支付日期和支付金额到这张表 ... 直到用户收货,我们就把这张表补充完整了。从而省去了多表 join 的过程。

3.4.2 设计流程

       累积型快照事实表的设计流程同事务型事实表类似,也可采用以下四个步骤,下面重点描述与事务型事实表的不同之处。

选择业务过程→声明粒度→确认维度→确认事实。

1)选择业务过程

       选择一个业务流程中需要关联分析的多个关键业务过程,多个业务过程对应一张累积型快照事实表(对比我们之前事务型事实表选择业务的过程:选择感兴趣的业务过程,一个业务过程对应一张事务事实表)。

2)声明粒度

       精确定义每行数据表示的是什么,尽量选择最小粒度。

3)确认维度

       选择与每个业务过程相关的维度,需要注意的是,每各业务过程均需要一个日期维度。

4)确认事实

       选择各业务过程的度量值。

第4章 维度建模理论之维度表

4.1 维度表概述

       维度表是维度建模的基础和灵魂。前文提到,事实表紧紧围绕业务过程进行设计,而维度表则围绕业务过程所处的环境(何人何时何地)进行设计。维度表主要包含一个主键和各种维度字段,维度字段称为维度属性

4.2 维度表设计步骤

1)确定维度(表)

       在设计事实表时,已经确定了与每个事实表相关的维度,理论上每个相关维度均需对应一张维度表。需要注意到,可能存在多个事实表与同一个维度都相关的情况(比如下单表和支付表这两个事务事实表都存在用户id这个维度外键),这种情况需保证维度的唯一性,即只创建一张维度表。另外,如果某些维度表的维度属性很少(比如支付方式表没有必要去单独创建一个维度表,因为它就一个支付方式字段),则可不创建该维度表,而把该表的维度属性直接增加到与之相关的事实表中,这个操作称为维度退化

pay_id 支付方式
1 微信
2 支付宝
3 银联

       注意:前面我们说事实表只有两种字段:维度外键和度量指标,这里我们引入了第三种字段:维度退化字段。

2)确定主维表和相关维表

       此处的主维表和相关维表均指业务系统中与某维度相关的表。例如业务系统中与商品相关的表有sku_info,spu_info,base_trademark,base_category3,base_category2,base_category1等,其中sku_info就称为商品维度的主维表(通常情况下粒度最细的是主维表),其余表称为商品维度的相关维表。维度表的粒度通常与主维表相同。

3)确定维度属性

       确定维度属性即确定维度表字段。维度属性主要来自于业务系统中与该维度对应的主维表和相关维表。维度属性可直接从主维表或相关维表中选择,也可通过进一步加工得到。

确定维度属性时,需要遵循以下要求:

(1)尽可能生成丰富的维度属性

       维度属性是后续做分析统计时的查询约束条件、分组字段的基本来源,是数据易用性的关键。维度属性的丰富程度直接影响到数据模型能够支持的指标的丰富程度。

(2)尽量不使用编码,而使用明确的文字说明,一般可以编码和文字共存。

      比如支付方式,如果有这样一张维度表用 1 代表微信、2 代表支付宝、3代表银联,而不是使用文字,那么维度表那么多如果很多都包含这样的编码,之后用起来还得专门去字典表(一般对于这种编码系统会专门建字典表dic)里去查。所以我们最好使用文字作为维度属性或者蚊子和编码都作为维度属性。

(3)尽量沉淀出通用的维度属性

       有些维度属性的获取需要进行比较复杂的逻辑处理,例如需要通过多个字段拼接得到(加工)。为避免后续每次使用时的重复处理,可将这些维度属性沉淀到维度表中。比如活动表中:满多少金额减多少,满多少件打几折这种复杂的逻辑处理涉及到多个维度字段,我们需要进行沉淀。

4.3 维度设计要点

4.3.1 规范化与反规范化

       规范化是指使用一系列范式设计数据库的过程,其目的是减少数据冗余,增强数据的一致性。通常情况下,规范化之后,一张表的字段会拆分到多张表。

       反规范化是指将多张表的数据冗余到一张表,其目的是减少join操作(空间换时间),提高查询性能。

       在设计维度表时,如果对其进行规范化,得到的维度模型称为雪花模型,如果对其进行反规范化,得到的模型称为星型模型(星型模型更加适合数据分析)。

       数据仓库系统的主要目的是用于数据分析和统计,所以是否方便用户进行统计分析决定了模型的优劣。采用雪花模型,用户在统计分析的过程中需要大量的关联操作,使用复杂度高,同时查询性能很差,而采用星型模型,则方便、易用且性能好。所以出于易用性和性能的考虑,维度表一般是很不规范化的。

4.3.2 维度变化

       维度属性通常不是静态的,而是会随时间变化的(比如用户表的手机号,比如省份表),数据仓库的一个重要特点就是反映历史的变化,所以如何保存维度的历史状态是维度设计的重要工作之一。保存维度数据的历史状态,通常有以下两种做法,分别是全量快照表拉链表

1)全量快照表

       离线数据仓库的计算周期通常为每天一次,所以可以每天保存一份全量的维度数据到一个分区。这种方式的优点和缺点都很明显。

       优点是简单而有效,开发和维护成本低,且方便理解和使用。

       缺点是浪费存储空间,尤其是当数据的变化比例比较低时。

       比如上面这张用户表,从 2019-01-01 到 2019-05-11并没有数据变化,但是它还是每天全量的进行保存。

2)拉链表(重点)

       拉链表的意义就在于能够更加高效的保存维度信息的历史状态。

(1)什么是拉链表

       拉链表,记录每条信息的生命周期,一旦一条记录的生命周期结束,就直接重新开始一条记录,并把当前日期放入生效开始信息。

       如果当前信息至今有效,就在生效结束日期中填入一个极大值(如 9999-12-31)

(2)为什么要做拉链表

       拉链表适合于:数据会发生变化,但是变化频率并不高的维度(即:缓慢变化维)。英文拉链 zip 也可以翻译为 压缩,所以拉链表也可以理解为压缩表。

       比如:用户信息的变化就不并不高,所以如果按照每日全量的方式保存效率很低。

(3)如何使用拉链表

       拉链表同样是维度表,所以我们依然是用事实表和它去做关联,关联的时候的规则同样是哪一天发生的事实去 join 哪天的维度状态。现在的问题是我们如何通过拉链表获得那一天的全量状态。

       对于最新数据,我们可以直接查询满足状态结束日期为 9999-12-31 的数据。对于某天的数据,比如 2023-12-1 我们只要要求 状态开始日期 <= 2023-12-1 <= 状态结束日期 即可。

4.3.3 多值维度

       多值维度是一种现象,是在我们设计事实表时可能存在的一种现象。如果事实表中一条记录在某个维度表中有多条记录与之对应,称为多值维度。例如,下单事实表中的一条记录为一个订单(这种事实表在创建时没有考虑周全),一个订单可能包含多个商品,所会商品维度表中就可能有多条数据与之对应。

       针对这种情况,通常采用以下两种方案解决。

       第一种:降低事实表的粒度,例如将订单事实表的粒度由一个订单降低为一个订单中的一个商品项。

       第二种:在事实表中采用多字段保存多个维度值,每个字段保存一个维度id。这种方案只适用于多值维度个数固定的情况。如果多维度个数不固定可以使用 Hive 的复杂数据类型(比如数组)。

       建议尽量采用第一种方案解决多值维度问题。

4.3.3 多值属性

       多值属性同样是一种现象,是在我们设计维度表时可能存在的一种现象。多值维表中的某个属性同时有多个值,称之为“多值属性”,例如商品维度的平台属性(比如品牌、CPU,是否支持快充)和销售属性(比如规格、颜色、尺寸),每个商品均有多个属性值。

       针对这种情况,通常有可以采用以下两种方案。

       第一种:将多值属性放到一个字段,该字段内容为key1:value1,key2:value2的形式,例如一个手机商品的平台属性值为“品牌:华为,系统:鸿蒙,CPU:麒麟990”。

       第二种:将多值属性放到多个字段,每个字段对应一个属性。这种方案只适用于多值属性个数固定的情况。

4.4 维度模型对同步策略的影响

       这是我们上一篇同步策略中划分的对于不同业务表对应不同的同步策略,现在我们可以看到这样的现象:

  • 对于事务事实表将来需要用到的表通常采用增量同步
  • 对于周期快照事实表将来需要用到的表通常采用全量同步
  • 对于累积事实表将来需要用到的表通常采用增量同步
  • 对于每日全量快照维度表将来需要用到的表通常采用全量同步
  • 对于拉链表将来需要用到的表通常采用增量同步

比如对上面的 cart_info(购物车信息) 这个表,我们既做一个事务事实表,也要做周期快照事实表。上面的 user_info 虽然更像是维度表,但是因为它将来要做为拉链表,所以采用增量同步。


离线数仓(五)【数据仓库建模】(2)https://developer.aliyun.com/article/1532390

相关实践学习
数据库实验室挑战任务-初级任务
本场景介绍如何开通属于你的免费云数据库,在RDS-MySQL中完成对学生成绩的详情查询,执行指定类型SQL。
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
相关文章
|
15天前
|
Cloud Native 数据管理 OLAP
云原生数据仓库AnalyticDB产品使用合集之是否可以创建表而不使用分区
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
337 2
云原生数据仓库AnalyticDB产品使用合集之是否可以创建表而不使用分区
|
15天前
|
Cloud Native 关系型数据库 MySQL
云原生数据仓库AnalyticDB产品使用合集之如何修改云ADB MySQL版的默认LIMIT
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
52 21
|
15天前
|
SQL Cloud Native 关系型数据库
云原生数据仓库AnalyticDB产品使用合集之如何进行一键诊断
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
350 7
|
15天前
|
存储 SQL Cloud Native
云原生数据仓库AnalyticDB产品使用合集之热数据存储空间在什么地方查看
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
15天前
|
存储 关系型数据库 MySQL
云原生数据仓库AnalyticDB产品使用合集之是否支持rdb数据库实时同步
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
145 4
|
15天前
|
Cloud Native 关系型数据库 MySQL
云原生数据仓库AnalyticDB产品使用合集之是否支持mysql_fdw 和clickhousedb_fdw外部数据包装器
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
111 4
|
15天前
|
Cloud Native 关系型数据库 OLAP
云原生数据仓库AnalyticDB产品使用合集之 orcale的行转列函数wm_concat 在pg版本有对应的相关函数吗
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
15天前
|
SQL Cloud Native 关系型数据库
云原生数据仓库AnalyticDB操作报错合集之执行sql的进程报错:"unknown connection id",是什么导致的
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
742 3
|
15天前
|
SQL Cloud Native 关系型数据库
云原生数据仓库AnalyticDB操作报错合集之报错代码"[31004, 2023121817001319216817200303151051107] : Compiler failed and interpreter is disabled"是什么导致的
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
679 3
|
15天前
|
Cloud Native 关系型数据库 MySQL
云原生数据仓库AnalyticDB产品使用合集之是否支持修改主键
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
279 3

热门文章

最新文章