1. 维度建模基础:什么是维度建模?为什么需要维度建模?维度建模与ER建模的区别

1.1 什么是维度建模?

维度建模,说白了就是一种面向分析查询的数据组织方式。我习惯把它比作「超市货架」——商品按类别分区,每个货架有固定标签,顾客想找什么一眼就能看到。

在技术层面,维度建模由两张核心表构成:事实表和维度表。事实表记录业务事件,比如一笔订单、一次点击;维度表描述业务环境,比如谁买的、什么时候买的、在哪个门店买的。

核心思想:用「事实」记录发生了什么,用「维度」描述在什么环境下发生的。两者通过外键关联,形成星型结构。

举个例子。我在做电商数仓时,订单事实表里存的是订单金额、数量、折扣;时间维度表里存年月日、是否节假日、第几周。查询时把两张表一关联,就能回答「今年春节那周,华东区女装品类销售额是多少」这种问题。

1.2 为什么需要维度建模?

你想想看,业务方问的问题大多是「按XX维度看XX指标」。比如:

  • 按月份看销售额趋势
  • 按区域看用户活跃度
  • 按品类看退货率

这些查询天然就是「事实+维度」的结构。如果用ER建模,你得join七八张表才能拿到数据,性能差不说,业务方也看不懂。

我个人总结维度建模有三大好处:

  1. 查询快——星型结构减少了join次数,数据库优化器很喜欢这种模式
  2. 好理解——业务方看到「时间」「门店」「产品」这些维度,一眼就明白
  3. 易扩展——加一个新维度,只需要加一张维度表,不影响已有结构

我的经验:在金融项目中,业务方经常临时要加「渠道来源」维度。如果是ER建模,得改好几张表;维度建模只需要加一张dim_channel表,关联事实表的channel_id就行。改完当天就能上线。

1.3 维度建模与ER建模的区别

很多刚入行的朋友会问:为什么不用ER建模?ER建模不是更规范吗?

嗯,这里要注意——ER建模和维度建模的定位完全不同。

ER建模的目标是消除数据冗余,保证数据一致性,适合OLTP系统。比如银行转账系统,你肯定不希望同一笔钱在两张表里不一致。ER建模通过三范式把数据拆成很多小表,更新时只改一处,很安全。

但代价是什么?查询时得join很多表。我见过一个保险系统的ER模型,查一次保单详情要join 12张表。这种模型给业务方做报表,基本跑不动。

维度建模正好反过来——适当冗余,优先查询性能。维度表里会有一些冗余字段,比如时间维度表里同时存了年月日、季度、节假日标志。虽然占点存储,但查询时不用再计算,速度飞快。

我把两者的核心区别整理成了一张表:

对比维度 ER建模 维度建模
目标 消除冗余,保证一致性 提升查询性能,易理解
适用场景 OLTP(事务处理) OLAP(分析查询)
表结构 多张细粒度小表 事实表+维度表
范式 第三范式(3NF) 星型/雪花型
冗余度 低 中高
查询性能 差(多表join) 好(星型join)
业务理解 难(需懂数据模型) 易(维度直观)

避坑提醒:我曾经在一个项目中,试图用ER建模做数仓,结果业务方每次提需求都要我解释表关系。后来改成维度建模,他们自己就能写SQL查数据。所以记住——OLTP用ER,OLAP用维度建模,别混用。

1.4 维度建模的核心概念

在深入之前,先理清几个关键概念。这些是我在项目中每天都要打交道的:

  • 事实(Fact):业务事件的度量值,可加总。比如销售额、订单数、点击量
  • 维度(Dimension):描述事实的环境属性。比如时间、地点、产品
  • 粒度(Granularity):事实表中每一行代表什么。比如「每笔订单一行」还是「每天汇总一行」
  • 退化维度(Degenerate Dimension):事实表中的业务编号,比如订单号,不单独建维度表

举个例子,电商订单事实表的粒度通常是「订单行级别」——每个商品一行。如果粒度是「订单级别」,那一个订单买了3件商品就只能看到总金额,看不到每个商品的明细。

我的习惯:设计事实表时,先确定粒度。粒度定错了,后面所有分析都会出问题。我一般会问业务方:「你们最细要看什么?」答案就是粒度。

1.5 维度建模的常见模式

维度建模有几种经典模式,我简单介绍一下:

  1. 星型模式:一张事实表在中间,多张维度表在周围,像星星一样。最常用,查询性能最好。
  2. 雪花模式:维度表进一步规范化,拆成子维度。比如产品维度拆成产品表和品类表。查询时多一层join,性能稍差。
  3. 星座模式:多张事实表共享维度表。比如订单事实表和退货事实表共用时间、产品维度。

我个人推荐优先用星型模式。雪花模式虽然省点存储,但查询时多一层join,得不偿失。除非维度表特别大(比如上亿行),否则别用雪花。

下面这张图展示了星型模式的核心结构:

星型模式结构图 事实表 订单事实表 订单金额 | 数量 | 折扣 时间维度 年月日 | 季度 | 节假日 产品维度 品类 | 品牌 | 价格 门店维度 区域 | 城市 | 类型 客户维度 等级 | 性别 | 年龄 date_key product_key store_key customer_key 事实表通过外键与维度表关联,形成星型结构 查询时只需join一次,性能远优于ER模型

1.6 什么时候该用维度建模?

不是所有场景都适合维度建模。我总结了几条判断标准:

  • 查询模式固定:业务方经常按几个固定维度看指标
  • 历史数据为主:数据写入后很少修改,主要是查询
  • 性能要求高:需要在秒级返回聚合查询结果
  • 业务方自助分析:他们自己写SQL或拖拽BI工具

反过来,如果你的系统主要是事务处理(比如订单录入、库存扣减),或者数据经常更新,那还是老老实实用ER建模。

一句话总结:维度建模是面向分析的,ER建模是面向事务的。选哪个,取决于你的用户是「看报表的」还是「做操作的」。

1.7 本章小结

这一章我们聊了维度建模的核心思想、为什么需要它、以及它和ER建模的区别。说白了,维度建模就是用事实+维度的方式,让数据查询又快又好理解。

记住几个关键点:

  • 事实表存度量,维度表存描述
  • 星型模式是首选,简单高效
  • OLTP用ER,OLAP用维度建模
  • 先定粒度,再设计表结构