4、数据建模基础:实体关系模型(ER图)、维度建模(星型、雪花型)、事实表与维度表
数据建模这事儿,说白了就是给数据画「蓝图」。你想想看,盖楼之前总得有个设计图吧?数据仓库也一样。没有建模,数据就是一盘散沙,查起来费劲,用起来更费劲。
我个人习惯把建模分成两大流派:ER 模型和维度模型。前者适合 OLTP 系统,后者是数据仓库的标配。今天咱们重点聊聊后者,因为你在数据目录里查业务数据,十有八九碰到的都是维度模型。
核心观点:维度建模是数据仓库的「通用语言」。学会了它,你就能快速理解一张表是干什么的,以及它和其他表怎么关联。
4.1 实体关系模型(ER图)—— 先打个底
ER 图,全称 Entity-Relationship Diagram。它用实体(矩形)、属性(椭圆)、关系(菱形)来描述现实世界。我在项目中见过不少同学一上来就画 ER 图,结果画着画着就晕了——因为业务太复杂,实体太多,关系乱成一团。
ER 图的核心是规范化,目的是消除数据冗余。比如一个订单系统,会把客户信息、商品信息、订单信息拆成多张表,通过外键关联。这样做的好处是更新方便,但查询时得 JOIN 一大堆表,性能堪忧。
我的经验:ER 图适合做「业务梳理」,不适合做「查询优化」。如果你只是想快速找到某个业务指标对应的表,别死磕 ER 图,直接看维度模型更高效。
4.2 维度建模 —— 数据仓库的基石
维度建模是 Ralph Kimball 老爷子提出的。它的核心思想就八个字:「事实」和「维度」。你想想看,任何业务分析无非就是回答两个问题:
- 发生了什么? —— 事实(比如销售额、订单量)
- 在什么背景下发生的? —— 维度(比如时间、地点、产品)
把这两个东西分开存,查起来就快多了。我刚开始做数据仓库时,总想把所有字段塞到一张大表里,结果表又宽又慢,维护起来想哭。后来老老实实按维度建模来,世界清净了。
4.2.1 事实表 —— 记录「发生了什么」
事实表是维度建模的核心。它存储的是可度量的数值,比如销售额、数量、时长。事实表通常很大,行数动辄上亿,但列数不多。
事实表有三种类型:
| 类型 | 特点 | 例子 |
|---|---|---|
| 事务事实表 | 每行记录一个业务事件 | 订单表(每笔订单一行) |
| 周期快照事实表 | 按固定周期汇总 | 每日库存快照表 |
| 累积快照事实表 | 记录一个流程的多个阶段 | 订单生命周期表(下单→支付→发货→完成) |
避坑指南:我曾经犯过一个错——把维度属性直接塞进事实表。比如在订单事实表里存了「客户姓名」。结果客户改名后,历史数据全乱了。记住:事实表只存度量值和外键,别存描述性字段。
4.2.2 维度表 —— 描述「背景信息」
维度表是事实表的「说明书」。它存储的是描述性属性,比如时间维度表里有年、月、日、季度、节假日。维度表通常比较「宽」,行数相对较少。
维度表的设计有几个要点:
- 代理键:别直接用业务主键,用自增的代理键。为什么?因为业务主键可能会变(比如客户 ID 重新编号),代理键不会。
- 退化维度:如果某个维度只有一个属性(比如订单号),可以直接放在事实表里,不用单独建维度表。
- 缓慢变化维度(SCD):维度属性会变,比如客户地址变了。处理策略有覆盖(SCD1)、新增行(SCD2)、新增列(SCD3)。我个人最常用 SCD2,保留历史轨迹。
4.3 星型模型 vs 雪花型模型
这是维度建模的两个经典「造型」。说白了就是维度表怎么组织的问题。
4.3.1 星型模型
星型模型长这样:中间一张事实表,周围一圈维度表,像星星一样辐射出去。维度表不继续拆分,直接「反规范化」。
优点:查询简单,JOIN 次数少,性能好。
缺点:数据冗余,维度表更新时可能不一致。
我个人的经验是:80% 的场景用星型模型就够了。别为了追求「完美」把模型搞复杂,查询慢才是真痛点。
4.3.2 雪花型模型
雪花型模型是星型模型的「规范化」版本。维度表继续拆分成子维度表,比如「产品维度」拆成「产品表」和「品类表」。
优点:数据冗余少,节省存储,更新一致性好。
缺点:查询需要 JOIN 更多表,性能下降。
什么时候用雪花型?我一般在维度表特别「宽」、属性层次特别多的时候用。比如一个产品维度有 50 个属性,其中 20 个是品类相关的,那就拆成两张表。
| 对比维度 | 星型模型 | 雪花型模型 |
|---|---|---|
| 查询性能 | 高(JOIN 少) | 低(JOIN 多) |
| 存储空间 | 大(有冗余) | 小(无冗余) |
| 维护复杂度 | 低 | 高 |
| 适用场景 | 大多数分析场景 | 维度层次复杂、存储敏感 |
4.4 实战:如何用维度模型理解业务数据
假设你拿到一个电商数据仓库,里面有几十张表。怎么快速找到「2024年Q3每个品类的销售额」?
- 找事实表:先找包含「销售额」字段的表。大概率是
fact_order或fact_sales。 - 找维度表:需要时间维度(Q3)和产品维度(品类)。找到
dim_date和dim_product。 - 关联:事实表通过外键
date_key和product_key关联维度表。 - 查询:按时间维度的季度、产品维度的品类分组,SUM 销售额。
你看,只要理解了星型模型的结构,查数据就像拼乐高一样简单。
小技巧:在数据目录里,事实表通常以 fact_ 开头,维度表以 dim_ 开头。看到这个命名规则,你就知道该怎么 JOIN 了。
4.5 本章知识体系图
下面这张图帮你理清数据建模的核心脉络。从 ER 模型到维度模型,从星型到雪花型,一目了然。
4.6 小结
数据建模不是纸上谈兵。你理解了 ER 图、维度模型、星型和雪花型,再看数据目录里的表,心里就有底了。记住几个关键点:
- 事实表存「度量」,维度表存「描述」
- 星型模型是默认选择,别过度设计
- 代理键和 SCD 是维度表设计的「坑」,踩过就知道疼