Star Schema vs Snowflake Schema
One layer of joins vs many — and the same answer
Star schemas denormalize dimensions for simple, fast queries; snowflake schemas normalize them into hierarchies. Modern warehouses and BI made stars the default, but snowflakes still win for highly-shared hierarchies.
What you will learn
- Draw each schema shape from the same business model
- Explain the query-performance trade-off of each
- Decide which fits the team's BI and warehouse
What is this?
A star schema stores each dimension as one denormalized table around the fact; a snowflake schema normalizes dimensions into linked lookup tables (product → category → department). Modern warehouses and BI layers make the star the pragmatic default; snowflakes reduce redundancy when hierarchies are heavily shared.
Why do you need it?
- The choice changes join complexity and portability of your analyst SQL.
- Renaming it 'snowflake' (vs the platform) is a common source of confusion — worth naming clearly.
- BI tools and columnar warehouses have tilted the cost equation toward stars.
Mental model
A phone list with all details on one card (star) vs a card that points to other cards (snowflake)
Denormalized vs normalized dimensions
One-card lookup is faster per query but repeats some data; chaining cards saves space but adds hops and pages to flip.
How it works
- Star: dimension holds category/region attributes inline; one join hop from fact to dimension.
- Snowflake: dimension holds foreign keys to hierarchy tables (category separate from product).
- Star benefits: simpler SQL, fewer joins, better for columnar compression of repeated values, BI-friendly.
- Snowflake benefits: no repeated category text, single source of truth for a hierarchy, smaller footprint in row stores.
- Modern guidance: prefer star; only snowflake where a hierarchy is genuinely shared and referenced.
Star vs snowflake shapes.
Examples
The same report, two shapes
-- STAR: one hopSELECT sum(f.gross_amount) FROM fact_sales fJOIN dim_product p ON f.product_key = p.product_keyWHERE p.category = 'Widgets'; -- SNOWFLAKE: two hopsSELECT sum(f.gross_amount) FROM fact_sales fJOIN dim_product p ON f.product_key = p.product_keyJOIN dim_category c ON p.category_key = c.category_keyWHERE c.name = 'Widgets';Snowflake adds a hop but stores the category once; star repeats category on every product row.
In production
- A columnar warehouse with dictionary compression happily repeats category across product rows — star wins.
- An org with a shared region/currency hierarchy used by many facts snowflakes just that hierarchy.
- BI tools with star-auto-join accelerate analysts without them hand-writing joins.
Best practices
- Default to star; add normalized hierarchies only for genuinely shared lookups.
- If you snowflake, keep the fact→dimension keyed path short so SQL stays readable.
- Document which hierarchy you denormalized and why, so a later team doesn't 'normalize it back'.
Common mistakes
- Snowflaking everything because 'normalized is more correct' and paying join taxes on every report.
- Star-denormalizing a volatile hierarchy that itself needs versioning, then blasting history.
- Naming a star model 'snowflake' in docs and confusing everyone about the platform.
Debugging tips
- A report that is slower with more hops often needs the star denormalized dimension, not more indexes.
- Watch for category values duplicated inconsistently inside star rows — a classic denormalization drift.
- Compare plan join count between an analyst's SQL and the intended star shape.
Interview checkpoint
Quick quiz
In a star schema, how many joins separate a fact from its dimension attribute?
Snowflake schemas eliminate all join hops in analyst queries.