核心概念与指标:维度与度量、星型模型与雪花模型、数据立方体、预聚合与物化视图
好,咱们正式开始聊实时 OLAP 的核心概念。说实话,很多同学一开始就被这些术语搞晕了——维度、度量、星型、雪花、Cube……感觉像在学天书。其实没那么复杂,这些东西都是前人踩过无数坑之后总结出来的套路。我做了这么多年架构,今天就把这些概念掰开了揉碎了讲给你听。
维度与度量:分析世界的两个基本视角
先问个问题:你平时看报表的时候,最关心什么?
无非两件事:看什么和怎么看。
- 度量(Measure):就是你要分析的那个“数”。比如销售额、订单量、用户数、点击次数。它是可量化的,能加能减能求平均。
- 维度(Dimension):就是你从哪个角度去看这个数。比如按时间看、按地区看、按商品品类看、按用户性别看。
我举个例子你就明白了。假设你是电商公司的数据分析师,老板问你:“昨天卖了多少?”
“卖了 100 万。”——这是度量。
老板又问:“哪个城市卖得好?”
“北京 30 万,上海 25 万,深圳 20 万……”——这就是按“城市”这个维度去切分度量。
说白了,维度就是坐标轴,度量就是坐标轴上的值。你每多一个维度,分析的自由度就多一层。
星型模型与雪花模型:两种经典的表结构设计
有了维度和度量的概念,接下来就要考虑怎么在数据库里组织这些表了。这里有两个经典模型——星型和雪花。
星型模型
星型模型长什么样?中间一张事实表,周围一圈维度表,像星星一样辐射出去。
- 事实表:存度量数据,比如订单金额、数量。它通常很大,每天几千万甚至上亿条。
- 维度表:存维度属性,比如时间、地区、商品。它相对较小,几千到几万条。
事实表通过外键关联到维度表。查询的时候,先过滤维度表,再 JOIN 事实表,效率很高。
雪花模型
雪花模型是星型模型的“规范化”版本。它把维度表进一步拆分成多个子表,形成层级结构。
比如地区维度,星型模型里是一张表:region_id, province, city, district。雪花模型会拆成三张表:province表、city表、district表,然后通过外键关联。
这样做的好处是节省存储空间,避免数据冗余。但坏处也很明显——查询的时候要多 JOIN 好几张表,性能会下降。
| 对比项 | 星型模型 | 雪花模型 |
|---|---|---|
| 存储空间 | 较大(有冗余) | 较小(无冗余) |
| 查询性能 | 快(JOIN 少) | 慢(JOIN 多) |
| 维护复杂度 | 低 | 高 |
| 适用场景 | OLAP 查询、大宽表 | 数据仓库 ETL、维度层级深 |
数据立方体:多维分析的终极武器
星型模型和雪花模型解决的是“怎么存”的问题。那“怎么查”呢?尤其是那种“按任意维度组合做聚合查询”的场景——比如“2024 年第一季度,华东地区,男性用户,购买电子产品,总金额是多少?”
这种查询如果每次都去扫描事实表,再 GROUP BY 几个维度,性能肯定扛不住。这时候就需要数据立方体(Data Cube)了。
数据立方体,说白了就是预计算好的多维聚合结果。它把各个维度组合下的度量值提前算好,存起来。查询的时候直接取结果,不用再扫描原始数据。
举个例子。假设你有三个维度:时间、地区、商品。数据立方体会预先算好以下所有组合:
- 总销售额(不按任何维度分组)
- 按时间分组
- 按地区分组
- 按商品分组
- 按时间+地区分组
- 按时间+商品分组
- 按地区+商品分组
- 按时间+地区+商品分组
一共 2^3 = 8 种组合。维度越多,组合数呈指数增长。这就是所谓的“维度爆炸”问题。
下面这张图展示了数据立方体的核心结构:
预聚合与物化视图:空间换时间的经典策略
数据立方体听起来很美好,但有个现实问题:计算量太大。尤其是实时场景下,数据源源不断地进来,你要不停地更新这些预计算结果。
这时候就需要预聚合(Pre-aggregation)和物化视图(Materialized View)这两个工具了。
预聚合
预聚合,就是在数据写入的时候,顺便把聚合结果算好。比如原始数据是一条一条的订单,你可以在写入时同时更新“今日总销售额”、“今日各城市销售额”等聚合结果。
常见的预聚合策略有三种:
- 全量预聚合:所有维度组合都算。适合维度少、数据量小的场景。
- 部分预聚合:只算高频查询的组合。适合维度多、数据量大的场景。
- 分层预聚合:按时间粒度分层。比如先算分钟级,再算小时级,最后算天级。上层可以复用下层的结果。
物化视图
物化视图是数据库层面的一个功能。它把查询结果物理存储下来,后续查询直接读这个存储结果,而不是重新执行 SQL。
和普通视图的区别?普通视图只是个虚拟表,每次查询都要重新计算。物化视图是真实存在的表,数据是预先算好的。
在实时 OLAP 里,物化视图通常配合增量更新使用。数据源有新数据进来,物化视图只更新受影响的那部分聚合结果,而不是全量重算。
| 特性 | 普通视图 | 物化视图 |
|---|---|---|
| 存储方式 | 虚拟(不存数据) | 物理(存数据) |
| 查询性能 | 慢(每次重新计算) | 快(直接读结果) |
| 数据新鲜度 | 实时(查询时计算) | 取决于刷新策略 |
| 维护成本 | 低 | 高(需要定期刷新) |
| 适用场景 | 低频查询、数据量小 | 高频查询、数据量大 |
把这些概念串起来
好了,咱们把今天讲的东西串一下:
- 维度与度量:分析的基本单元。维度是“怎么看”,度量是“看什么”。
- 星型模型与雪花模型:表结构设计的选择。实时场景下,我推荐星型模型。
- 数据立方体:多维预聚合的思想。把各种维度组合的聚合结果提前算好。
- 预聚合与物化视图:实现数据立方体的具体技术手段。空间换时间,但要注意平衡。
这些概念不是孤立的。实际项目中,你会先用星型模型设计表结构,然后基于事实表和维度表定义数据立方体,最后通过物化视图把预聚合结果落地。每一步都有取舍,每一步都有坑。