1.1 维度的基本概念
维度是维度建模的基础和灵魂。在维度建模中,将度量称为“事实”,将环境描述称为“维度”,维度是用于分析事实所需要的多样环境。
维度使用主键标识其唯一性,主键也是确保与之相连的任何事实表之间存在引用完整性的基础。主键有代理键和自然键,它们都是用来表示某维度的具体值。但代理键是不具有业务含义的键,一般用于处理缓慢变化维;自然键是具有业务含义的键。比如商品,在ETL过程中会生成商品维表唯一标识的代理键,但没有业务含义。商品本身的自然键是商品ID。
1.2 维度的基本设计方法
维度设计过程就是确定维度属性(维度字段)的过程,如何生成维度属性,以及所生成的维度属性的优劣,决定了维度使用的方便性,成为数据仓库易用性的关键。正如Kimball所说的,数据仓库的能力直接与维度属性的质量和深度成正比。
下面以淘宝的商品维度为例对维度设计方法进行详细说明。
第一步:选择维度或新建维度。作为维度建模的核心,在企业级数据仓库中必须保证维度的唯一性。
第二步:确定主维表。此处的主为表一般是ODS表。以淘宝商品维度为例,商品表是与前台商品中心系统同步的,即是主维表。
第三步:确定相关维表。根据对业务的梳理,确定哪些表和主维表存在关联关系,并选择其中的某些表用于生成维度属性。
第四步:确定维度属性。本步骤主要包括两个阶段,其中第一个阶段是从主维表中选择维度属性或生成新的维度属性;第二个阶段是从相关维表中选择维度属性或生成新的维度属性。以淘宝为例,从主维表和类目、SPU、卖家、店铺等相关维表中选择维度属性或生成新的维度属性。
确定维度属性的几点提示:
(1)尽可能生成丰富的维度属性。
(2)尽可能多地给出包括一些富有意义的文字性描述。
(3)区分数值型属性和事实。
(4)尽量沉淀出通用的维度属性。
1.3 维度的层次结构
维度中的一些描述属性以层次方式或一对多的方式相互关联,可以被理解为包含连续主从关系的属性层次。可以根据维度的上下关系上钻或下钻。
1.4 规范化和反规范化
规范化是指将属性层次被实例化为一系列维度,而不是单一的维度,也被称为雪花模式。
反规范化则是与规范化相反,将属性层次合并到单一的维度。
1.5 一致性维度和交叉探查
Kimball的数据仓库总线架构提供了一种分解企业级数据仓库规划任务的合理方法,通过构建企业范围内一致性维度和事实来构建总线架构。
在针对不同数据域进行迭代构建或并行构建时,存在很多需求是对于不同数据域的业务过程或者同一个数据域的不同业务过程合并在一起观察。比如对于日志数据域,统计了商品维度的最近一天PV和UV;对于交易数据域,统计了商品维度的最近一天的下单GMV。现在将不同数据域的商品的事实合并在一起进行数据探查,如计算转化率等,称为交叉探查。
2.1 维度整合
维表整合的内容:业务含义相同的表统一,有以下几种集成方式:
下面看看表级的整合方式:
2.2 水平拆分
维度通常按类别或类型进行细分。在一系列的维表里,有共同的维度属性,也有各自独特的维度属性,针对这种情况,我们主要有两种解决方案:方案一是将维度的不同分类实例化为不同的维度,同时在主维度中保留公共属性;方案二是维护单一维度,包含所有可能的属性。
选择哪个方案,需要考虑以下上原则:
2.3 垂直拆分
根据维度属性的热度不同、使用频率不同来垂直拆分维度字段。按可扩展性、效能和易用性,设计主从维度。主维表存放稳定、产出时间早、热度高的属性;从维表存放变化快、产出晚、热度低的属性。
2.4 历史归档
定期将历史数据归档至历史维表。
3.1 缓慢变化维
数据仓库的重要特点之一反映历史变化,所以如何处理维度的变化是维度设计的重要工作之一。
第一种处理方式:重写维度值。不需要保留历史数据。
以商品所属类目变化情况为例,具体描述:
变化前商品表和订单表
商品Key | 商品ID | 商品标题 | 所属类目 | 其他维度属性 |
1 | SP001 | title1 | 类目1 | ... |
订单key | 日期key | 商品key | 交易金额 | 其他事实 |
D1 | 2017-10-01 | SP001 | 1000.0 | .... |
变化后商品表和订单表
商品key | 商品ID | 商品标题 | 所属类目 | 其他维度属性 |
1 | SP001 | title1 | 类目2 | .... |
订单key | 日期key | 商品key | 交易金额 | 其他事实 |
D1 | 2017-10-01 | SP001 | 1000.0 | ... |
D1 | 2017-10-02 | SP001 | 2000.0 | ... |
第二种处理方式:插入新的维度行。
第三种处理方式:添加维度列。
3.2 快照维表
数据仓库对来源表进行全量或增量数据抽取,不做任何变动。
3.3 极限存储
历史拉链存储就是处理维度模型中缓慢变化的一种方式,通过新增两个时间戳字段(start_dt和end_dt),将所有以天为粒度的变更数据记录下来。通常分区字段也是时间戳字段。这种存储方式存在下游数据使用方理解障碍,而且使用start_dt和end_dt做分区,随着时间的推移,分区数量会极度膨胀,而现行的数据库体系都有分区数量限制。
针对上述两个问题,阿里提出采用极限存储方式处理,分月做历史拉链表,及每月月初重现开始做历史拉链表。(极限存储有局限性,不太适合高变化率的数据,不太建议使用)
3.4 微型维度
微型维度的创建是通过将一部不稳定的属性从主维度中移除,并将它们放置到拥有自己代理键的新表中来实现。(不建议使用,ETL加工逻辑复杂)
4.1 递归层次
维度递归层次,按照层次是否固定分为均衡层次结构和非均衡层次结构。例如:地区,分别是乡镇/街道、区县、城市、省份、国家,这类有固定层次为均衡层次结构;公司之间的关系,每个公司可能存在一个母公司,但可能没有一级、二级等层级关系,对这种没有固定层次为非均衡层次结构。
在递归层次中进行上钻和下钻,会使用到递归。而在很多数据仓库系统和商业智能工具不支持递归SQL,且用户使用递归SQL的成本较高。所以,建议对层次结构进行处理:
1 层次结构扁平化
通过建立维度固定数量级别的属性来实现,可以一定程度上解决上钻和下钻的问题。 但可能存在以下上方面问题:
(1)针对上钻和下钻之前,必须知道所属的类目层次。
(2)所此层次为叶子层(即没有下层),则无法下钻和上钻。针对这个问题,可以此层次的上层或下层填本层科目,虚拟科目。
(3)扁平化仅包含固定数量的级别,对均衡层次结构,可以通过预留级别的方式解决,但扩展性较差。
2 层次桥接表
针对扁平化所存在的问题,可以使用桥接表的方式解决,即中间设置中间对照表,关联两者。该方法适合解决更宽泛的分析问题,灵活性好;但复杂性高,使用成本高。
4.2 行为维度
省略
4.3 多值维度
省略
4.4 多值属性
省略
4.5 杂项维度
省略