2. OLAP 核心概念:维度、度量、星型模型、雪花模型、数据立方体
好,咱们正式开始啃 OLAP 的硬骨头。这一章的概念,说白了就是整个实时分析大厦的砖和图纸。你想想看,如果连「砖」和「图纸」都分不清,后面怎么盖楼?
我个人习惯,讲概念之前先给个全景图。下面这张图,就是 OLAP 世界的「世界观」——它告诉你数据从哪来,怎么组织,最后怎么被分析。
2.1 维度:你看数据的角度
维度是什么?我举个例子你就懂了。假设你在看一张销售报表,你可能会想:「这个月哪个产品卖得最好?」——这里的「产品」就是一个维度。你还会想:「哪个地区的销售额最高?」——「地区」又是一个维度。
所以,维度就是你观察数据的「视角」或「坐标轴」。它通常是描述性的信息,比如时间、地点、产品、客户、渠道。
维度的核心特征:
- 离散值:维度取值是有限的、可枚举的(比如省份、月份)。
- 有层级:时间维度可以按「年 → 季度 → 月 → 日」下钻。
- 用于分组和筛选:SQL 里的 GROUP BY 和 WHERE 子句,操作的就是维度。
我在项目中遇到过最典型的坑:有人把「订单金额」也当成了维度。结果报表里维度表膨胀得厉害,查询慢得要命。记住,能加总、能平均的字段,大概率是度量,不是维度。
2.2 度量:你要算的数值
度量,就是你要分析的那个「数字」。比如销售额、订单数量、用户停留时长、点击次数。说白了,度量是可以被聚合计算的值。
常见的聚合操作就那几种:
| 聚合函数 | 含义 | 示例 |
|---|---|---|
| SUM | 求和 | 总销售额 |
| COUNT | 计数 | 订单笔数 |
| AVG | 平均值 | 客单价 |
| MAX / MIN | 最大值 / 最小值 | 最高单笔金额 |
| DISTINCT COUNT | 去重计数 | 独立访客数 (UV) |
我的经验: 实时 OLAP 里,度量最好提前定义好「预聚合」策略。比如你经常要查「每分钟的 PV」,那就提前算好存起来,别每次都扫全量数据。我曾经帮一个客户优化,把查询从 30 秒降到了 200 毫秒,核心就是做了预聚合。
2.3 星型模型:最常用的数据组织方式
星型模型长什么样?你想象一颗星星:中间一张「事实表」,周围一圈「维度表」。事实表记录业务事件(比如一笔订单),维度表记录描述信息(比如产品名称、客户地址)。
为什么叫星型?因为从事实表连接到各个维度表,形状像星星的辐射线。
-- 事实表:销售订单事实
CREATE TABLE fact_sales (
order_id INT,
product_key INT, -- 关联到产品维度表
customer_key INT, -- 关联到客户维度表
date_key INT, -- 关联到时间维度表
store_key INT, -- 关联到门店维度表
quantity INT, -- 度量:数量
amount DECIMAL -- 度量:金额
);
-- 维度表:产品维度
CREATE TABLE dim_product (
product_key INT PRIMARY KEY,
product_name VARCHAR(100),
category VARCHAR(50),
brand VARCHAR(50)
);
-- 维度表:时间维度
CREATE TABLE dim_date (
date_key INT PRIMARY KEY,
full_date DATE,
year INT,
quarter INT,
month INT,
day INT
);
星型模型的优点:
- 查询性能好:表关联少,SQL 简单。
- 易于理解:业务人员一看就懂。
- 适合 OLAP 场景:大多数 BI 工具都针对星型模型优化。
2.4 雪花模型:更规范,但更复杂
雪花模型是星型模型的「升级版」。它把维度表进一步「规范化」——拆成更细的子表。比如产品维度,可以拆成「产品表」和「品类表」,品类表再关联到产品表。
这样做的好处是数据冗余更少,更新维护更方便。但代价是查询时要多关联几张表,性能会下降。
我曾经踩过的坑: 刚开始做数仓时,我追求「完美范式」,把维度表拆得特别细,搞了七八层雪花。结果业务方跑一个报表要等一分钟。后来我学乖了:OLAP 场景下,星型模型优先,除非你有明确的维护理由,否则别轻易上雪花。
| 对比维度 | 星型模型 | 雪花模型 |
|---|---|---|
| 表结构 | 一张事实表 + 多张维度表 | 维度表进一步拆分 |
| 数据冗余 | 较高 | 较低 |
| 查询性能 | 快(关联少) | 慢(关联多) |
| 维护成本 | 低 | 高 |
| 适用场景 | OLAP 分析、BI 报表 | 数据仓库底层、ETL 清洗 |
2.5 数据立方体:OLAP 的终极产物
数据立方体(Cube),听起来很玄乎,其实没那么复杂。它就是按所有维度组合预先算好的度量结果集。
你想想看:如果我有「时间、产品、地区」三个维度,每个维度有 10 个取值,那所有组合就是 10×10×10 = 1000 种。数据立方体就是把这 1000 种组合的销售额都提前算好存起来。查询时直接取,不用再扫描原始数据。
这就是 OLAP 能「秒级响应」的秘密——空间换时间。
数据立方体的核心操作:
- 上卷 (Roll-up):从细粒度到粗粒度,比如从「日」汇总到「月」。
- 下钻 (Drill-down):从粗粒度到细粒度,比如从「年」拆到「季度」。
- 切片 (Slice):固定一个维度,看其他维度。比如只看「2024年」的数据。
- 切块 (Dice):固定多个维度,形成一个子立方体。比如看「2024年华东地区的销售数据」。
- 旋转 (Pivot):交换维度位置,换个视角看数据。
我建议你记住一个比喻:数据立方体就像一块魔方。每个面是一个维度,每个小方块是一个度量值。你转动魔方,就是在做上卷、下钻、切片、旋转。是不是好理解多了?
避坑指南: 数据立方体不是越大越好。维度太多会导致「维度爆炸」——组合数量呈指数增长,存储和计算成本都扛不住。我曾经见过一个 Cube 有 20 个维度,结果构建一次要跑 6 小时。后来我们只保留了最常用的 8 个维度,构建时间降到了 15 分钟。所以,选维度时要有取舍,只选业务真正关心的。