• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

数仓维度设计

武飞扬头像
和风与影
帮助2

1.维度设计基础

1.1 维度的基本概念
  • 维度是什么:度量-事实。环境-维度。维度就是分析事实所需要的环境。
  • 维度做什么:维度属性是查询约束条件、分组和报表标签生成的基本来源,是数据易用性的关键。一般用来查询约束分类汇总排序
  • 维度的获取:报表中获取;与业务人员交流中发现;经常出现在 by 语句内。
  • 维度用主键标识其唯一性。
1.2 维度的基本设计方法

以淘宝的商品维度为例:

  • 选择或新建维度:保证维度的唯一性。比如商品维度,有且只有一个维度定义。
  • 确定主维表:一般是 ODS 表,之间与业务系统同步。
  • 确定相关维表:确定哪些表与主维表存在关系,选择其中某些表生成维度属性。例如商品维度,商品与类目、SPU、卖家、店铺等维度存在关系。
  • 确定维度属性:首先从主维表中选择维度属性或生成新的维度属性;然后从相关维表中选择维度属性或生成新的维度属性。例如商品维度,从主维表,以及类目、SPU、卖家、店铺等相关维度中选择或生成维度属性。

确定维度的提示:

  • 尽可能丰富
  • 尽可能多给出富有意义的文字性描述,不应是编码,而是真正的文字
  • 区分数值型属性和事实。数值型字段是事实还是维度,可以参考字段的一般用途。一般离散值是维度可能性大,连续值是事实可能性大。但不绝对。
    • 通常用于查询约束条件或分组统计:维度属性;例如商品价格用于统计价格区间的商品数量,此时是维度。
    • 通常用于度量:事实;例如商品价格用于统计某类目商品的平均价格,此时是事实。
  • 尽量沉淀出通用的维度属性。有些维度属性的获取需要复杂的逻辑处理,或者通过多表关联,或者单表的不同字段混合处理,或者单表的某个字段解析。例如:商品是否在线,需要商品状态为 0 和 1 且商品上架时间小于等于当前时间,则是在线商品,否则是非在线商品。
1.3 维度的层次结构

维度中的一些描述属性有层次,例如商品属于类目,类目属于行业,类目中最低级的是叶子类目,叶子类目属于二级类目,二级类目属于一级类目。

通过向报表中添加连续的维度细节级别,实现在层次结构中钻取。

例如:

最高层:

日期 行业 一级类目 GMV
20200101 ALL ALL 1000亿

钻取至行业:

日期 行业 一级类目 GMV
20200101 行业1 ALL 400亿
20200101 行业2 ALL 300亿
20200101

钻取至一级类目:

日期 行业 一级类目 GMV
20200101 行业1 cat1 200亿
20200101 行业1 cat2 100亿
20200101 行业1
20200101 行业2 catX 50亿
20200101 行业2
1.4 规范化和反规范化

规范化:雪花模型,需要大量关联,查询性能差。

学新通

反规范化:维度的属性层次合并到单个维度中。
学新通

1.5 一致性维度和交叉探查

一致性维度:数据仓库总线架构的重要基石。

交叉探查:对不同数据域的业务过程,或统一数据域的不同业务过程,合并在一起观察,例如日志数据域统计了商品维度一天的 PV 和 UV,交易数据域统计了商品维度近一天的 GMV。将不同数据域的商品的事实合并在一起进行数据探查,比如计算转化率,称为交叉探查。

不同数据域重复的维度,其维度格式和内容不一致,会导致交叉探查无法进行。解决:

  • 共享维表:例如商品、卖家、买家、类目等维度有且只有一个。
  • 一致性上卷:其中一个维度的维度属性是另一个维度的维度属性的子集,且两个维度的公共维度属性结构和内容相同。例如:商品维度和类目维度,类目维度的属性是商品维度的属性的子集,这样基于类目交叉探查不会有问题。
  • 交叉属性:两个维度部分维度属性相同。比如商品维度中有类目属性,卖家维度中有主营类目属性,可以在相同类目属性上进行不同业务过程的交叉探查。

2.维度设计高级主题

2.1 维度整合

内容:

  • 命名规范统一:例如 uid 和 user_id
  • 字段类型统一:相同和相似的字段类型统一
  • 公共代码及代码值的统一
  • 业务含义相同的表统一

形式:

  • 垂直整合:不同来源,相同的数据集,存储的信息不同。比如淘宝会员下,有会员基础信息表、扩展信息表、等级信息表、天猫会员表,将其全表整合至会员维度模型中,丰富其维度属性。
  • 水平整合:不同来源,不同的数据集,子集之间无交叉或部分交叉。例如蚂蚁金服的数仓采集了淘宝会员、1688 会员、支付宝会员。整合时,交叉的要去重;不交叉的考虑子集的自然键是否冲突,不冲突可以将各子集的自然键作为整合后的表的自然键,或设置超自然键。
2.2 水平拆分

问题:

维度通常可以按类别细分。例如商品都有价格、标题、类型、上架时间、类目,但航旅类商品还有独特的维度属性,比如酒店、景点、门票等都有子集独特的维度属性。

拆分的原则:

  • 扩展性:业务、逻辑变化时能快速扩展,核心模型相对稳定。
  • 效能:牺牲一定的存储成本,达到性能和逻辑的优化。
  • 易用性:可理解性高,访问复杂度低。

拆分的依据:

  • 依据维度的不同分类的属性差异情况。定义一个主维度存放公共属性,同时定义多个子维度,除了包括公共属性,还包括特殊属性。比如商品维度、航旅商品维度。公共属性保证核心维度的稳定性,扩展子维度的方式保证模型的扩展性。
  • 依据业务的关联程度。关联性低的业务耦合在一起弊大于利。比如淘宝商品和 1688 商品,底层技术统一,但属于不同 BU,一般不会互相调用。
2.3 垂直拆分

问题:

  • 某些维度属性来源产出时间早,某些时间晚;
  • 某些维度热度高、使用频繁,某些较少使用;
  • 某些维度属性经常变化,某些较稳定。

拆分的原则:同水平拆分。

拆分的方法:设计主从维度。

  • 主维表存放稳定、产出时间早、热度高的属性;
  • 从维表存放变化快、产出时间晚、热度地的属性。
2.4 历史归档

比如前台不再使用的历史数据。

策略:

  1. 同前台策略。问题:前台策略复杂,经常变化,沟通维护成本高。适用于前台归档策略简单、不频繁变化时。
  2. 同前台策略但采用数据库变更日志的方式。简单易行,但前台要求数据库的物理删除只有在归档时才执行,应用中的删除只是逻辑删除。
  3. 自定义归档策略。

3.维度变化

3.1 缓慢变化维

缓慢变化维是因为现实世界中,维度的属性不是静态的,会随着时间流逝缓慢变化。处理方法:

  • 重写维度值:不保留历史,始终取最新数据。
  • 插入新的维度行:保留历史数据,维度值变化前的事实和过去的维度值关联,维度值变化后的事实和当前的维度值关联。缺点:不能将变化前后的记录归一化。
  • 添加维度列:事实可以归一化到新的或旧的维度。
3.2 快照维表

Kimball 的建模中必须使用代理键作为主键,处理缓慢变化维。但实践中未使用,因为分布式计算系统不存在事务,生成唯一全局代理键难度大,而且代理键增加 ETL 的复杂性。

实际使用快照处理缓慢变化维。例如每天存一份全量商品快照数据,作为商品维度。

优点:简单,方便,理解性好,开发维护成本低。

弊端:浪费存储。

3.3 极限存储

历史拉链存储:缓慢变化维的第二种处理方式。通过新增 start_dt 和 end_dt,将变更记录下来。

缺点:下游使用方理解障碍,数据分析师和前端人员不理解,有解释成本。采用 start_dt 和 end_dt 做分区,分区极度膨胀。

极限存储的做法:

  • 透明化:底层还是拉链存储,上层做了视图或 Hive 里的 hook,对下游用户透明。
select * from A where ds=20200101;
# 等价于
select * from A_EXST where start_dt<=20200101 and end_dt>20200101
  • 分月做历史拉链表:假如用 start_dt 和 end_dt 做分区,那么一年的分区最多 365 * 364 / 2 = 55430 个。如果每个月月初重新开始做历史拉链表,一年最多 12 * (1 (30 29) / 2) = 5232 个。

极限存储能压缩存储成本,对下游透明。但产出效率低,通常要 t-2。变化频率高不能节约成本。额外处理:

  • 极限存储前有一个全量存储表,保留最近一段时间的全量分区数据,历史数据通过映射关联到极限存储表。用户只访问全量存储表。
  • 部分频繁变化的字段需要过滤。例如用户表中的积分。
3.4 微型维度

频繁变化的属性假如维度表,导致极限存储没有意义。将频繁变化的属性从维度表中移除,放置到全新的维表中。或使用垂直拆分,保证主维度的稳定性。或者使用微型维度。

原理:将不稳定的属性从主维度移除,放到拥有自己代理键的新表中。这些属性之间没有直接关系,不存在自然键。通过为每个组合创建新行的一次性过程来加载数据。比如用户维度,注册日期、性别、省份信息不变,VIP 等级、信用评价会变。假如 VIP 共 8 个值 -1~6,信用共 18 个值,那么微型维度共有 8 * 18 = 144 条记录。代理键 144 个。

学新通

4.特殊维度

4.1 递归层次

均衡层次:例如类目,叶子类目、三级类目、二级类目、一级类目;地区,乡镇/街道、区县、城市、省份、国家。

非均衡层次:公司之间,每个公司存在一个母公司,但没有一级、二级关系。

由于不支持递归 SQL,所以需要在维度模型中对此层次结构进行处理。

4.1.1层次结构扁平化

每个类目保存一条记录,对于高层类目,没有低层类目,底层类目设为空。

  • 上钻下钻前,必须知道所属的类目层级。
  • 对于非平衡层次,通过预留级别解决,扩展性差。
  • 统计时,假如统计三级类目,三级类目为空的就取二级类目,二级仍未空就取一级类目。
  • 对上述问题可以采用扁平化回填,例如下表:
    学新通

扁平化回填:

学新通

4.1.2 层次桥接表

不需要预先知道所属层级,不需要回填。灵活性好,复杂性高,成本高。以类目为例:
学新通

类目树如下:

学新通

类目桥接表的内容如下:
学新通

4.2 行为维度

定义:与事实相关,如交易、物流等,称为行为维度或事实衍生维度。比如用户常用地址维度,卖家主营品牌维度。都需要统计计算才能得到。

加工:

  • 另一维度的过去行为,例如买家最近一次登录。
  • 快照事实行为维度,如买家信用分。
  • 分组事实行为维度,将数值型转换为枚举值,例如买家信用分数划分为等级。
  • 复杂逻辑事实行为维度,例如商品热度,根据访问、收藏、加购、交易综合计算。

处理方式:冗余至维度表或单独加工成维度表。

4.3 多值维度

事实表的一条记录,在某维表中有多条记录与之对应。比如一次购买了多种商品。处理方式:

  • 降低事实表的粒度:数仓中,关注子订单粒度,一个子订单只有一种商品。
  • 多字段:比如买房,夫妻共同买,但合同已经是最细粒度无法拆分。可以预留字段:其他买方。
  • 桥接表。事实表和维度表中开发一个分组表。例如刚刚的买房问题:

学新通

4.4 多值属性

例如每个商品下面,有一个或多个 SKU。处理方式:

  • 保持维度主键不变,多值属性放在维度的一个属性字段中,该字段下通过 k-v 对存放。扩展性好,使用麻烦。
  • 保持维度主键不变,多值属性放在维度的多个属性字段中。扩展性差,字段数量不固定。
  • 维度主键变化,一个维度值存放多条记录。比如商品 SKU 维表,每个商品有多少个 SKU 就有多少记录,主键是商品 ID 和 SKU 的 ID。扩展性好,使用方便。
4.5 杂项维度

由操作型系统中的指示符或标志字段组合而成,不在一致性维度中。比如交易订单的交易类型字段,包括话费充值、司法拍卖等。

解决:建立杂项维度,事实表保存外键。
学新通

欢迎关注。
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiabfjb
系列文章
更多 icon
同类精品
更多 icon
继续加载