趋近智
尽管星形模式因其简洁性和查询性能而成为维度建模的默认标准,但雪花模式是另一种方法,它更注重结构效率和数据完整性。雪花模式对维度表进行规范化,将数据分解成多个相关联的表,而非将其合并成一个单一的扁平结构。
这种设计呈现出类似雪花的形状:一个中心事实表连接到维度表,而这些维度表又连接到其他子维度表。本节审视了其架构差异、存储与计算之间的权衡,以及规范化维度能够带来益处的具体情形。
星形和雪花设计的主要区别在于它们如何处理维度内的层次关系。在星形模式中,层次级别(例如产品、类别和品牌)被反规范化到一个单一的 Dim_Product 表中。这会引入冗余;字符串“电子产品”可能会在数千个产品行的“类别”列中出现。
雪花模式通过更严格地遵循第三范式(3NF)来消除这种冗余。它将层次结构分离到不同的表中。产品表包含一个指向类别表的外部键,而类别表可能包含一个指向品牌或部门表的外部键。
以下图表描绘了标准星形模式结构在转换为雪花设计时如何扩展。
雪花模式结构中,维度分支成子维度。
Dim_Product表不直接存储类别名称,而是引用一个Dim_SubCategory表。
将维度雪花化的决定直接影响查询的复杂度和执行时间。在分析环境中,目标通常是快速聚合大量数据。
考虑一个按产品类别计算总销售额的查询。
在星形模式中: 数据库引擎在事实表和产品维度之间执行一次连接。类别名称已经存在于产品维度中。
SELECT
p.category_name,
SUM(f.sales_amount) as total_sales
FROM fact_sales f
JOIN dim_product p ON f.product_key = p.product_key
GROUP BY p.category_name;
在雪花模式中: 引擎必须遍历关系链。为了获取类别名称,它将事实表连接到产品表,产品表连接到子类别表,子类别表再连接到类别表。
SELECT
c.category_name,
SUM(f.sales_amount) as total_sales
FROM fact_sales f
JOIN dim_product p ON f.product_key = p.product_key
JOIN dim_subcategory sc ON p.subcategory_key = sc.subcategory_key
JOIN dim_category c ON sc.category_key = c.category_key
GROUP BY c.category_name;
每次额外的 JOIN 操作都会产生计算成本。尽管现代查询优化器效率高,但连接多个大表的开销并非为零。如果 N 是事实表中的行数,而 M 是涉及的维度表数量,解决这些关系的复杂性会增加,这可能会影响交互式仪表板的延迟。
过去,存储空间昂贵,这使得雪花模式因其减少文本冗余而具有吸引力。在 Dim_Country 表中存储字符串“美利坚合众国”一次,比在 Dim_Customer 表中存储数百万次更节省空间。
然而,现代云数据仓库(如 Snowflake、BigQuery 和 Redshift)使用列式存储。列式格式能够使用游程编码(RLE)等技术高效压缩重复数据。
如果一列中值 V 重复出现 k 次,RLE 将其存储为一对 (V,k),而不是 V,V,…,V。因此,在现代系统中,星形模式中反规范化的存储开销可以忽略不计。雪花模式中额外连接的计算成本通常超过了微不足道的存储节省。
尽管在一般分析中更倾向于星形模式,“雪花化”在特定情形下是合适的:
Dim_Store 表可能引用 Dim_Employee 表来识别店经理。这是一种雪花化形式,常被称为“舷外维度”。以下图表描绘了模式规范化(雪花化)与查询复杂性及存储影响之间的普遍关系。
随着模式从星形向雪花演变,数据冗余减少,但获取数据所需的连接复杂性显著增加。
对于大多数分析工作负载而言,星形模式是更优选择。它简化了编写自己的 SQL 或使用 BI 工具的最终用户的心智模型。Tableau 或 PowerBI 等工具能够针对扁平化维度生成更高效的查询。
然而,不应将其视为教条。在数据湖屋的“银层”或“富化层”,雪花设计可能用于维护干净的主数据,然后再将其扁平化为星形模式,用于最终的“金层”或服务层。这种方法在上游获得了规范化的维护优势,同时在下游提供了反规范化的查询性能。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造