数据建模方法论

数据建模的核心问题是:如何把业务概念转化为便于查询和分析的表结构。初学者最常见的错误是把 OLTP 的第三范式直接搬到 OLAP 上——结果查询需要 JOIN 20 张表,性能一塌糊涂。

一、星型模型(Star Schema)

最经典的数据仓库建模方式:一张事实表 + 多张维度表。

1
2
3
4
5
6
7
8
9
10
11
12
13
          ┌─────────┐
│ dim_user │ (用户维度)
└────┬────┘

┌─────────┐ │ ┌───────────┐
│dim_date │────┼────│dim_product │ (日期/产品维度)
└─────────┘ │ └───────────┘

┌──────────┴──────────┐
│ fact_orders │ (事实表)
│ user_id, product_id │
│ date_id, amount, qty │
└─────────────────────┘

优点:查询简单(事实表只需 JOIN 一次维度表)、性能好(维度表小可全缓存)。
缺点:维度表只支持单层,层级关系(如国家→省→市)需要冗余存储。

二、雪花模型(Snowflake Schema)

在星型模型基础上把维度表进一步规范化:

1
2
3
4
fact_orders
└─ dim_product
└─ dim_category
└─ dim_department

优点:消除冗余、节省存储。
缺点:查询 JOIN 更多、写 SQL 更复杂。实践中用得很少——存储成本远小于开发时间的成本。

三、数据仓库三层架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────┐
│ ODS(原始数据层) │
│ - 源系统数据的 1:1 镜像 │
│ - 不做清洗和转换 │
└────────────┬────────────────────┘
│ ETL
┌────────────▼────────────────────┐
│ DW(数据仓库层) │
│ - 清洗、去重、标准化 │
│ - 事实表 + 维度表 │
│ - 按业务域组织 │
└────────────┬────────────────────┘
│ 聚合
┌────────────▼────────────────────┐
│ DM(数据集市层) │
│ - 面向业务场景的聚合视图 │
│ - BI 报表直接对接 │
└─────────────────────────────────┘

四、宽表 vs 星型

维度 星型模型 宽表
JOIN 次数 1-3 次 0
存储空间 省(维度表只存一份) 冗余
开发效率 慢(需要建多张表) 快(一次跑完)
变更灵活 高(维度变更只改一张表) 低(需重建整张宽表)

实践建议:先建星型模型保证数据一致性,再在 DM 层建宽表加速 BI 查询。不要上来就建宽表——你的维度会变、事实会变、业务需求会变。星型模型的适配成本远低于宽表。

五、Data Vault(数据金库)

适用于超大规模、多数据源、频繁变更的企业场景:

1
2
3
Hub(业务实体)→ 比如 Hub_Customer(只存 business key
Link(实体关系)→ 比如 Link_Order_Customer
Satellite(描述信息)→ 比如 Sat_Customer_Name, Sat_Customer_Address

优点:极度灵活、适合增量加载、历史追踪完整。
缺点:表数量爆炸、查询需要大量 JOIN。初创公司不要用。

六、维度建模实践经验

实践 说明
退化维度 把维度属性直接放到事实表中(如订单号),避免不必要的 JOIN
缓慢变化维度 (SCD) Type1(覆盖), Type2(新增行+时间戳), Type3(新增列)
日期维度 永远要建——dim_date 包含年/季/月/周/日/节假日/是否周末
代理键 vs 自然键 外表用代理键(自增BIGINT),内部主键保证唯一

七、小结

数据建模的核心原则:让查询简单。星型模型是 80% 场景的最佳选择,宽表用于加速 BI,Data Vault 留给数据源 > 50 个的大型企业。不要在建模阶段过度设计——表和关系会随着业务理解加深而演进。