雪花模型是什么
雪花模型是把维度进一步规范化的建模方式:维度表再拆出子维度表,例如商品维度指向类目维度、类目再指向部门维度。它省掉冗余、结构更贴近源系统、层级关系清晰;代价是查询要穿过更多连接,BI 自助使用与变更维护都更繁琐。Inmon 的范式化观点与 Kimball 的维度建模在这里分道:前者倾向减少冗余,后者倾向可理解与查询效率。
基本信息
| 结构 | 维度表再拆子维度表,用外键串联层级 |
|---|---|
| 优点 | 冗余少、层级清晰、子维度独立更新方便 |
| 代价 | 连接层数多,查询与 BI 使用复杂,性能下降 |
| 适用场景 | 层级深、属性变更频繁且被多个主题共用的维度(组织、类目) |
| 常见折中 | 主体保持星型,仅对少数深层维度拆子表 |
| 对比对象 | 星型模型(维度不退化为单一宽维表) |
典型使用场景
- 组织架构维度:部门、事业部、公司多级独立维护,各主题共用
- 商品类目体系:类目、品类、行业多级,变更由商品主数据统一管理
- 集团多业务建模:多个事实表共用一套规范化维度,避免各建一份
- 源系统直连过渡:源端本身是范式化结构,短期不做退化处理
- 数据量极小的维表:规范化后连接成本可接受,优先减少冗余
雪花查询与星型对照
雪花查询与星型对照
-- 雪花:事实 → 商品维 → 类目维 → 日期维,连接层数多
SELECT d.year_month, c.cat_name, SUM(f.amount) AS amt
FROM fact_order f
JOIN dim_product p ON f.product_sk = p.product_sk
JOIN dim_category c ON p.cat_id = c.cat_id
JOIN dim_date d ON f.date_sk = d.date_sk
WHERE d.year_month = '2026-10'
GROUP BY d.year_month, c.cat_name;
-- 星型:类目属性已退化进商品维,连接更少、BI 生成 SQL 更简单
SELECT d.year_month, p.cat_name, SUM(f.amount) AS amt
FROM fact_order f
JOIN dim_product p ON f.product_sk = p.product_sk
JOIN dim_date d ON f.date_sk = d.date_sk
WHERE d.year_month = '2026-10'
GROUP BY d.year_month, p.cat_name;雪花与星型对比
| 维度 | 星型模型 | 雪花模型 |
|---|---|---|
| 维度表数量 | 少,维度退化进宽表 | 多,按层级拆子表 |
| 查询连接数 | 少,SQL 简单 | 多,BI 生成 SQL 复杂 |
| 存储冗余 | 有冗余,空间换效率 | 冗余少,省存储 |
| 维度更新 | 宽表整体重建成本高 | 子维度独立更新,影响面小 |
| 适用场景 | 面向分析的通用建模 | 层级深且被多主题共用的维度 |
数仓落地常见折中:主体星型,仅对层级深且独立维护的维度拆子表,避免全库雪花化。BI 工具的自动建模对多级连接支持有限,这也是实践中偏星型的原因之一。
子维度与主维度更新不同步会产生悬挂引用:类目挂在已删除的父类目下,分析时既不在任何分类里也不报错,属于最难发现的一类脏数据。