Snowflake schema

On this page 7

A snowflake schema is a dimensional design in which a central fact table is surrounded by normalized dimension tables, so that each dimension is split into a chain of related tables instead of one wide table. In data modeling for analytical databases, it is the normalized counterpart of the star schema: the diagram branches outward like the arms of a snowflake, which gives the pattern its name.

The design trades query simplicity for reduced redundancy. Attributes such as a product category or a customer’s country are stored once in their own table and referenced by key, which saves storage and simplifies maintenance of shared hierarchies, but every analytical query has to traverse more joins to reach them.

How a snowflake schema is structured

A snowflake schema is built from one or more fact tables that hold measurable events and dimension tables that describe those events, with some dimensions broken into sub-dimension tables. The fact table contains numeric measures such as quantity or revenue plus foreign keys to the first level of dimensions, exactly as in a star schema.

The difference appears inside the dimensions. In a product dimension, for example, the product table holds a foreign key to a subcategory table, which in turn references a category table, which may reference a department table. Each level of the hierarchy becomes its own table, typically keyed by a surrogate key, and the relationships between levels are one-to-many.

The table below traces a typical snowflaked product hierarchy from the fact table outward.

TableKey columnsDescriptive attributes
Sales factDate key, product key, store keyQuantity, net amount, discount
ProductProduct key, subcategory keyName, size, color, unit price
SubcategorySubcategory key, category keySubcategory name
CategoryCategory key, department keyCategory name, margin group
DepartmentDepartment keyDepartment name, manager
Example of a snowflaked product dimension

Snowflake schema compared with star schema

The snowflake schema differs from the star schema mainly in how far dimensions are normalized: a star schema keeps each dimension as one denormalized table, while a snowflake schema applies normalization, usually up to third normal form, to remove repeated attribute values. Both share the same fact table logic and grain.

AspectStar schemaSnowflake schema
Dimension structureOne wide table per dimensionSeveral linked tables per dimension
RedundancyRepeated hierarchy valuesEach value stored once
Joins per queryOne join per dimensionSeveral joins per dimension
Query authoringSimple for analysts and BI toolsMore complex, needs views or a semantic layer
StorageLarger dimensionsSmaller dimensions
Hierarchy maintenanceUpdate many rowsUpdate one row
Star and snowflake designs side by side

In practice the storage argument is weaker than it looks. Dimension tables are usually orders of magnitude smaller than fact tables, so the space saved by snowflaking rarely matters, and modern columnar engines compress repeated values efficiently. The more durable argument for snowflaking is consistency of shared hierarchies and easier integration with normalized source systems.

Query behavior and performance

A snowflake schema increases the number of joins needed to filter or group by higher-level attributes, and this is its main performance cost. Grouping sales by department in the example above requires four joins instead of one, and each join gives the optimizer another decision about order and method.

Many analytical engines include star-join optimizations that recognize a fact table and its dimensions and apply filters before scanning facts. These optimizations generally work best when dimensions are a single hop away. Snowflaked chains can still be optimized, but plan quality depends more heavily on accurate statistics and on the engine’s ability to push filters through several levels.

WorkloadEffect of snowflakingTypical mitigation
Filter on top-level attributeExtra joins before fact scanFlattened view over the chain
Ad hoc analyst queriesHigher authoring effort and error riskSemantic layer or BI model
Columnar warehouse scansModest overhead on small dimensionsUsually acceptable as is
OLAP cube processingLonger dimension processingPre-join during cube build
Dimension updatesFaster, fewer rows touchedNo mitigation needed
Effect of snowflaking on common workloads

When to choose a snowflake schema

A snowflake schema is the better choice when dimension hierarchies are large, shared or frequently changing, and when the people writing queries work through a modeling layer rather than raw SQL. Typical cases include product hierarchies reused by several fact tables, geographic hierarchies with many levels, and dimensions where one level has many attributes of its own.

  • Shared outrigger tables: a geography table referenced by customer, store and supplier dimensions keeps every location consistent.
  • Large, sparse attributes: a level with dozens of attributes used rarely can be split off to keep the main dimension narrow.
  • Normalized sources: when source systems already store hierarchies in separate tables, snowflaking can simplify loading and lineage.
  • Governance needs: a single row per category or region makes corrections and ownership clearer.

Many teams settle on a hybrid design: store dimensions in partly snowflaked form for maintenance, then expose flattened views or a semantic model to analysts. This keeps a single source of truth for each hierarchy while giving users the simple star-shaped interface they expect.

Design pitfalls

Most problems with snowflake schemas come from normalizing more than the queries require. Each extra level adds joins, foreign keys and load dependencies, so over-snowflaking can make a model fragile without delivering measurable benefits.

MistakeSymptomFix
Snowflaking every dimensionQueries with ten or more joinsKeep small dimensions flat
Natural keys between levelsBreakage when source codes changeUse surrogate keys
Ignoring history at each levelWrong historical rollupsDefine slowly changing rules per level
Optional parent levelsRows lost in inner joinsUse explicit unknown members
No flattened access layerAnalysts write inconsistent joinsPublish views or a semantic model
Common snowflake schema mistakes

History handling deserves particular care. When a product moves to another subcategory, the model must decide whether past sales stay with the old subcategory or move to the new one. In a snowflake design this slowly changing dimension decision has to be made consistently at every level of the chain.

The idea in brief

Imagine a sales record that says which product was sold. In a snowflake schema, the product points to its subcategory, the subcategory points to its category, and the category points to its department, much like a family tree written on separate cards.

Each fact is written down only once, so correcting a department name means changing one card. The price is that answering a question such as sales by department means following the chain card by card, which takes more effort than reading one combined sheet.

A practical scenario

A regional grocery chain builds a warehouse with sales, inventory and purchasing fact tables. All three need the same product hierarchy of about 60,000 products, 900 subcategories, 120 categories and 12 departments, and the merchandising team reorganizes categories several times a year.

The data team stores the hierarchy as a snowflaked product dimension with separate subcategory, category and department tables, each with surrogate keys and change history. A reorganization now updates a few category rows instead of tens of thousands of product rows, and all three fact tables reflect it at once.

For analysts, the team publishes a flattened product view that joins the chain into one wide table. Report authors query it as if it were a star schema, while the warehouse keeps a single, consistent definition of every category.