讲讲数仓的维度表(Dimension Table)
在数据仓库(Data Warehouse)的建模理论中,维度表(Dimension Table) 是核心概念之一。如果把数据分析比作拍电影,事实表(Fact Table) 是动作和剧情(发生了什么),而 维度表 就是背景设定、人物介绍和时间地点(环境上下文)。
以下是关于维度表的详细解析,涵盖定义、特征、分类以及设计原则。
1. 什么是维度表?
维度表主要用于存储描述性的属性数据。它回答了业务过程中的 “Who, What, Where, When, Why” 问题。
- 作用: 为事实表中的数值(度量)提供上下文环境。
- 用途: 在 SQL 查询中,维度表的列通常出现在
WHERE(筛选条件)和GROUP BY(分组统计)子句中。
举个例子(电商场景):
你有一条订单记录:“2023-10-01,用户小明买了2台iPhone 15,花费12000元”。
- 事实(Fact): 2台(数量),12000元(金额)。
- 维度(Dimension):
- 时间维度: 2023-10-01(是周几?是不是国庆假期?属于哪个季度?)
- 用户维度: 小明(性别?年龄?所在城市?会员等级?)
- 商品维度: iPhone 15(品牌是Apple?属于手机类目?颜色?)
2. 维度表的核心特征
维度表通常具有以下显著特征,概括为 “矮胖”:
- 行数相对较少(矮): 相比于事实表动辄亿级的交易记录,维度表的行数通常较少(例如商品表可能只有几十万行,用户表可能有几千万行,但仍少于交易流水)。
- 列数较多(胖): 维度表包含大量的描述性字段。例如“商品维度表”可能包含:商品ID、名称、描述、重量、颜色、品牌、一级类目、二级类目、上架时间等几十个字段。
- 主键(Primary Key): 每一行都必须由一个唯一的键标识。
- 代理键(Surrogate Key): 数仓内部生成的无业务含义的整数ID(推荐使用,性能好且解耦)。
- 自然键(Natural Key): 业务系统原本的ID(如身份证号、SKU编码)。
- 层级关系(Hierarchy): 维度内部往往包含层级结构,用于“钻取(Drill-down)”和“上卷(Roll-up)”。
- 例如: 国家 -> 省份 -> 城市 -> 区县。
3. 维度表 vs. 事实表
| 特性 | 维度表 (Dimension Table) | 事实表 (Fact Table) |
|---|---|---|
| 内容 | 描述性文本、属性 | 数值、度量、外键 |
| 用途 | 过滤、分组、标签 | 聚合计算 (Sum, Avg, Count) |
| 数据量 | 相对较小 (几千到几千万行) | 巨大 (亿级甚至更多) |
| 变化频率 | 缓慢变化 (Slowly Changing) | 快速增长 (每天新增大量记录) |
| 形态 | 宽表 (列多) | 窄表 (列少,主要是ID和数字) |
4. 维度表的关键类型
在数仓建设中,会遇到各种复杂的维度处理情况,以下是几种常见的类型:
A. 时间维度 (Date/Time Dimension)
这是每个数仓必须有的表。你不能只存一个 2023-10-27 的日期格式。你需要一张表来告诉分析师:
- 这一天是星期几?
- 是工作日还是周末?
- 是否是法定节假日?
- 属于哪个财政季度?
- 是否是促销日?
B. 缓慢变化维度 (SCD - Slowly Changing Dimensions)
维度属性并非一成不变(例如:用户从“北京”搬到了“上海”)。如何处理这种变化?
- SCD Type 1 (覆盖): 直接把“北京”改成“上海”。缺点:历史数据分析会出错(看起来他过去下的单也是在上海下的)。
- SCD Type 2 (保留历史 - 最常用): 增加一行新记录。旧记录标记为“过期”,新记录标记为“当前有效”。通常配合
Start_Date和End_Date字段使用。 - SCD Type 3 (增加列): 在同一行增加一列
Previous_City。只能保留最近一次的历史。
C. 退化维度 (Degenerate Dimension)
有些维度没有对应的维度表,直接保存在事实表中。
- 例子: 订单编号 (Order ID)。它具有维度的特征(唯一标识),但没有其他的属性(如颜色、大小)需要单独建表存储,所以直接放在事实表里。
D. 杂项维度 (Junk Dimension)
业务系统中可能有很多“标志位”或“状态码”(如:是否支付、是否发货、验证方式等)。
如果为每个标志位建一个维度表太繁琐,通常将这些低基数(Low Cardinality)的标志位组合在一起,放入一张单独的“杂项维度表”中。
5. 维度建模的两种模式
维度表的设计方式决定了数仓的模型架构:
星型模型 (Star Schema) —— 推荐
- 特点: 维度表是反范式化的。
- 做法: 把商品、类目、品牌都塞在一张“商品维度表”里。
- 优点: 查询时不需要关联太多表(Join 次数少),性能极快,易于理解。
- 缺点: 数据有冗余(“电子产品”这个词在表中重复出现万次)。但在大数据时代,存储空间是最廉价的,计算效率才是关键。
雪花模型 (Snowflake Schema)
- 特点: 维度表是规范化的。
- 做法: 商品表 -> 关联 -> 类目表 -> 关联 -> 品牌表。
- 优点: 数据无冗余,维护方便。
- 缺点: 查询时需要大量的 Join,性能较差。在大数据 OLAP 场景下通常不推荐。
6. 总结:如何设计一个好的维度表?
- 尽可能丰富: 属性越多越好,给分析师提供更多的切入角度(Slice and Dice)。
- 使用代理键: 不要直接用业务系统的ID做主键,防止业务系统ID复用或变更导致数仓混乱。
- 反范式化(宽表化): 尽量把相关属性整合到一张表中,牺牲存储换取查询速度(遵循 Kimball 建模理论)。
- 处理好历史变化: 明确哪些字段需要记录历史(SCD Type 2),哪些可以直接覆盖。
理解维度表,是理解数据分析“多维视角”的基础。如果事实表是数据的“骨架”,维度表就是数据的“血肉”。