第10章 维度设计
1.维度设计基础
- 维度的基本概念
(1)维度是什么
维度是维度建模的基础和灵魂。在维度建模中,将度量称为“事实”,将环境描述为“维度”,维度是用于分析事实所需所需的多样环境。
(2)维度属性是什么
维度所包含的表示维度的列,称为维度属性。维度属性是查询约束条件、分组和报表标签生成的基本来源,是数据易用性的关键。
(3)维度的作用
查询约束、分类汇总以及排序等。
(4)如何获取维度或维度属性
① 可以在报表中获取
② 可以在和业务人员的交谈中发现维度或维度属性。
(5)维度唯一性表标识
维度使用主键标识其唯一性,主键也是确保与之相连的任何事实表之间存在引用完整性的基础。
主键有两种:代理键和自然键,它们都是用于标识某维度的具体值。
代理键是不具有业务含义的键, 般用于处理缓慢变化维;
自然键是具有业务含义的键
- 维度的基本设计方法
维度的设计过程就是确定维度属性的过程,如何生成维度属性,以及所生成的维度属性的优劣,决定了维度使用的方便性,成为数据仓库易用性的关键。正如 Kimball 所说的,数据仓库的能力直接与维度属性的质量和深度成正比。
淘宝商品维度设计方法:
(1)选择维度或者新建维度,在数据仓库中要保证维度的唯一性,比如淘宝商品维度,有且只允许有一个维度定义。
(2)确定主维表,一般主维表是ODS表,直接与业务系统同步。
(3)确定相关维表, 根据对业务的梳理,确定哪些表和主维表存在关联,并选择其中的一些用来生成维度属性
(4)确定维度属性,包括从主维表和相关维表中选择维度属性或生成新的维度属性包含两个阶段:
第一个阶段是从主维表中选择维度属性或生成新的维度属性;
第二个阶段是从相关维表中选择维度属性或生成新的维度属性。
确定维度属性的几点提示:
① 尽可能生成丰富的维度属性
② 尽可能多地给出包括一些富有意义的文字描述
③ 区分数值型属性和事实
④ 尽量沉淀出通用的维度属性
- 维度的层次结构
维度中的一些描述属性以层次方式或一对多的方式相互关联,可以被理解为包含连续主从关系的属性层次。层次的最底层代表维度中描述最低级别的详细信息,最高层代表最高级别的概要信息。维度常常有多个这样的嵌入式层次结构。
- 规范化和反规范化
当属性层次被实例化为一系列维度,而不是单一的维度时,被称为雪花模式。大多数联机事务处理系统( OLTP )的底层数据结构在设计时采用此种规范化技术,通过规范化处理将重复属性移至其自身所属的表中,删除冗余数据
将维度的属性层次合并到单个维度中的操作称为反规范化。
采用雪花模式,用户在统计分析的过程中需要量的关联操作,使用复杂度高,同时查询性能很差;而采用反规范化处理,则方便、易用且性能好。
- 一致性维度和交叉探查
构建企业级数据仓库不可能一蹴而就,一般采用迭代式的构建过程。 数据仓库总线架构的重要基石之一就是一致性维度。在针对不同数据域进行迭代构建或者并行构建时,需要将不同数据域的业务过程或者同一数据域的不同业务 合并在一起观察。
将不同数据域的商品的事实合并在 起进行数据探 ,如计算转化率等,称为交叉探查。
如果不同数据域的计算过程使用的维度不 致,就会导致交叉探查存在问题。当存在重复的维度,但维度属性或维度属性值不一致时,会导致交叉探查无法进行或交叉探查结果错误。
结维度一致性的几种表现形式:
共享维表。 比如在阿里巴巴的数据仓库中,商品、卖家、买家、类目等维度有且只有一个。
一致性上卷,其中一个维度的维度属性是另 一个维度的维度属性的子集,且两个维度的公共维度属性结构和内容相同。
交叉属性 ,两个维度具有部分相同的维度属性。
2.维度设计高级主题
- 维度整合
(1)垂直整合
不同的来源表包含相同的数据集,只是存储的信息不同。
(2)水平整合
不同的来源表包含不同的数据集,不同子集之间无交叉,也可以存在部分交叉
- 维度拆分
数据模型设计的三个原则:
扩展性:当源系统、业务逻辑变化时,能通过较少的成本快速扩展模型,保持核心模型的相对稳定性。软件工程中的高内聚、低稠合的思想是重要的指导方针之一。
效能:在性能和成本方面取得平衡。通过牺牲一定的存储成本,达到性能和逻辑的优化。
易用性:模型可理解性高、访问复杂度低。用户能够方便地从模型中找到对应的数据表,并能够方便地查询和分析。
根据数据模型设计思想,在对维度进行拆分
(1)水平拆分
主要考虑如下两个依据:
① 是维度的不同分类的属性差异情况
② 是业务的关联程度
(2)垂直拆分
出于扩展性、产出时间、易用性等方面的考虑,设计主从维度。主维表存放稳定 产出时间早、热度高的属性;从维表存放变化较快、产出时间晚、热度低的属性。
- 历史归档
归档策略1:同前台归档策略,在数据仓库中实现前台归档算法,定期对历史数据进行归档。但存在一些问题,一是前台归档策略复杂,实现成本较高;二是前台归档策略可能会经常变化 导致数据仓库归档算法也要随之变化,维护和沟通成本较高。此方式适用于前台归档策略逻辑较为简单,且变更不频繁的情况。
归档策略2:同前台归档策略,但采用数据库变更日志的方式。对于如此庞大的数据量,阿里巴巴采用的数据抽取策略一般是通过数据库binlog 日志解析获取每日增量,通过增量 merge 全量的方式获取最新的全量数据。可以使用增量日志的删除标志 作为前台数据归档的标志。通过此标志对数据仓库的数据进行归档。此方式不需要关注前台归档策略,简单易行。但对前台应用的要求是数据库的物理删除只有在归档时才执行,应用中的删除只是逻辑删除。
归档策略3:数据仓库自定义归档策略。可以将归档算法用简单直接的方式实现,但原则是尽量比前台应用晚归档、少归档。避免出现数据仓库中已经归档的数据再次更新的情况
3.维度变化
- 缓慢变化维
缓慢变化维的提出是因为在现实世界中,维度的属性并不是静态的,它会随着时间的流逝发生缓慢的变化与数据增长较为快速的事实表相比,维度变化相对缓慢。
解决方式:
方式一:重新维度值,不保留历史数据。
方式二:插入新的维度行,维度值变化钱的事实和过去的维度值关联
方式三:添加维度列,是由于方式二不能将变化前后记录的事实归一为变化前或者变化后的维度。
- 快照维表
Kimball的维度建模理论中,必须使用代理键作为每个维表的主键,用于处理缓慢变化维。但是在阿里并没有使用。
(1)为什么不使用代理键呢?
数据量庞大,且对于分布式系统来说,不存在事务的概念。对每个表记录生成稳定的全局唯一的代理键难度很大(稳定指某条记录每次生成的代理键都相同)使用代理键会增加ETL复杂性,对开发和维度的成本很高。
(2)如何解决缓慢变化维呢?
采用快照的方式,每天保留一份全量快照数据,通过限定日期采用自然键进行关联就可。优点:简单而高效、使用方便好理解。缺点:存储浪费
- 极限存储
用来解决存储浪费的问题
数据存储记录:
历史拉链存储:
这种存储方式对于下游使用方存在一定 的理解障碍,特别ODS 数据面向的下游用户包括数据分析师、前端开发人员等,他们不怎么理解维度模型的概念,因此会存在较高的解释成本。另外,这种储方式用 start_dt和end_dt 做分区,随 时间的推移,分区数量会极度膨胀,而现行的数据库系统都有分区数量限制。
为了解决上述两个问题,阿里巴巴提出来用极限存储的方式来处理
① 透明化
② 分月做历史拉链存储
采用极限存储的处理方式,极大地压缩了全量存储的成本,又可以达到对下游用户透明的效果,是一种比较理想的存储方式。但是其本身也有一定 的局限性,首先,其产出效率很低,大部分极限存储通常需要t-2 其次,对于变化频率高的数据并不能达到节约成本的效果。因此在实际生产中,做极限存储需要进行一些额外的处理。
① 在做极限存储前有一个全量存储表 ,全量存储表仅保留最近一段时间的全量分区数据,历史数据通过映射的方式关联到极限存储表。即用户只访问全量存储表,所以对用户来说极限存储是不可见的。
② 对于部分变化频率频繁的宇段需要过滤。例如,用 户表中存在用户积分宇段,这种宇段的值每天都在发生变化,如果不过滤的话,极限存储就相当于每个分区存储一份全量数据,起不到节约存储成本的效果。
- 微型维度
将一部分不稳定的属性从主维度中移出,并将他们放到拥有自己代理键的新表中来。这些属性互相之间没有直接关联,不存在自然键。通过为每个组合创建新行的一次性过程来
加载数据。
优点:
可以解决维度的过度增长导致极限存储效果大打折扣的问题;
缺点:
① 微型维度的局限性,事先用所有可能值的组合加载的,要考虑每个属性的基数且是枚举值。
② ETL逻辑复杂,生成代理键和使用理键加工都很复杂
③ 破坏了维度的可浏览性,可能造成无法对应统计和未维护历史信息的问题
4.特殊维度
- 递归层次
递归层次指的是某维度的实例值的层次关系。
由于很多数据仓库系统和商业智能工具不支持递归 SQL ,且用户使用递归 SQL 的成本较高,所以在维度模型中,需要对此层次结构进行处理。
(1)层次结构扁平化:
降低递归层次使用复杂度的最简单和有效的方法是层次结构的扁平化,通过建立维度 的固定数级别的属性来实现,可以在一定程度上解决上钻和下钻的问题。对于均衡层次结构,采用扁平化最有效。
问题:
① 针对某类目上钻或者下钻之前,必须知道所属的类目层级
② 假设分三级类目统计最近一天的GMV,由于某些叶子类目直接是一级或二级目录,和交易事实表关联后,对应的三级类目为空,导致三级类目统计时(类目为10)的交易无法统计到。可以采用回填的方式,用的较多。
③ 扁平化仅包含固定数量的级别,对于非平衡层次结构可以通过预留级别的方式来解决,但扩展性差
(2)层次桥接表:
针对层次结构扁平化所存在的问题,可以采用桥接表的方式来解决,不需要预先知道所属层级,不需要回填,也可解决非均衡层次结构的问题。与扁平化方法相比,该方法适合解决更宽泛的分析问题,灵活性好;但复杂性高,使用成本高。
- 行为维度
(1)划分为以下几种
① 另一个维度 的过去行为,如买家最近一次访问淘宝的时间、 买家最近 次发生淘宝交易的时间等。
② 快照事实行为维度,如买家从年初截至当前的淘宝交易金额、买家信用分值 、卖家信用分值等。
③ 分组事实行为维度 ,将数值型事实转换为枚举值。如买家从年初截至当前的淘宝交易金额按照金额划分的等级 买家信用分值按照分数划分得到的信用等级等。
④ 复杂逻辑事实行为维度,通过复杂算法加工或多个事实综合加工得到。如前面提到的卖家主营类目,商品热度根据访问、收藏、加人购物车、交易等情况综合计算得到。
(2)行为维度的处理方式
将其冗余至现在的维度表中,买家信誉等级冗余到买家表加工成单独的行为表,如卖家主营类目
(3)原则:
避免维度快速增长,将商品热度加入现有的维表中会导致极限存储效果差避免耦合度过高,过多的业务耦合会导致维表刷新逻辑复杂、维护性差、产出延迟
- 多值维度
事实表的一条记录在某维表中有多条记录与之对应。比如一个订单,可能包含多个商品,交易父子订单。
常见的处理方式:
① 降低事实表的粒度,比如可以设置为子订单力度(商品力度)
② 采用多字段,比如房地产交易,有多个买受方。对于合同签订事实表,合同已经时此事实中最细力度了,可以用多字段的方式解决,有买受方一、买受方二。
③ 使用桥接表,需要谨慎使用,可能带来双重计算的风险。
- 多值属性
维表中的某个属性字段同时有多个值,称为多值属性。如每个商品有一到多个SKU(Stock Keeping Unit 库存量单位)、属性(不同尺码、颜色分类)
常见的处理方式:
① 保持主键不变,将多值属性放在维度的一个属性字段中,用k-v对的形式保存。
② 保持主键不变,将多值属性放在维度的多个属性字段,比如卖家主营类目就是取的TOP3,可以固定数量。
③ 维度主键发生变化,一个维度值存放多条记录,每个商品有多少SKU就有多少记录。数据容易膨胀
- 杂项维度
由操作系统中的指示符或者标志字段组合而成,不在一致性维度之列。
比如:交易订单的交易类型字段(话费充值、航旅);支付状态、物流状态;交易留言、交易属性(k-v对)、交易标签。