Star schema vs snowflake schema
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Короткий ответ
- Star schema (звезда) — fact в центре, dimension вокруг, dimension денормализованы
- Snowflake schema (снежинка) — то же, но dimension нормализованы на под-dimension
В DWH в 95% случаев побеждает star — быстрее, проще, понятнее.
Визуально
Star schema
dim_users
|
dim_date | dim_stores
\ | /
fact_orders
/
dim_productsОдно fact в центре, 4 dimension вокруг — напоминает звезду.
Snowflake schema
dim_country
|
dim_users ------- dim_city
|
fact_orders dim_category ----- dim_department
| |
dim_products -----------------Dimension имеет свои «подветки» — получается снежинка.
Пример star schema
-- dimension: products (ОДНА таблица, денормализованная)
CREATE TABLE dim_products (
product_id INT PRIMARY KEY,
name VARCHAR(200),
category VARCHAR(100), -- повторяется для товаров в одной категории
category_description TEXT,
department VARCHAR(50), -- повторяется
department_manager VARCHAR(100)
);
-- fact: orders
CREATE TABLE fact_orders (
order_id INT PRIMARY KEY,
product_id INT REFERENCES dim_products(product_id),
user_id INT,
date_id INT,
amount DECIMAL(10,2)
);Запрос:
SELECT p.category, SUM(f.amount) AS revenue
FROM fact_orders f
JOIN dim_products p ON p.product_id = f.product_id
GROUP BY p.category;Один JOIN — просто и быстро.
Пример snowflake schema
-- dimension разбита на 3 нормализованные таблицы
CREATE TABLE dim_departments (
department_id INT PRIMARY KEY,
department VARCHAR(50),
manager VARCHAR(100)
);
CREATE TABLE dim_categories (
category_id INT PRIMARY KEY,
category VARCHAR(100),
description TEXT,
department_id INT REFERENCES dim_departments(department_id)
);
CREATE TABLE dim_products (
product_id INT PRIMARY KEY,
name VARCHAR(200),
category_id INT REFERENCES dim_categories(category_id)
);Запрос на те же данные:
SELECT c.category, SUM(f.amount) AS revenue
FROM fact_orders f
JOIN dim_products p ON p.product_id = f.product_id
JOIN dim_categories c ON c.category_id = p.category_id
GROUP BY c.category;Два JOIN вместо одного.
Сравнение
| Критерий | Star | Snowflake |
|---|---|---|
| Нормализация | денормализован | нормализован |
| JOIN в запросах | меньше | больше |
| Размер хранилища | больше (дубли) | меньше |
| Производительность запросов | быстрее | медленнее |
| Понятность для BI-инструментов | высокая | средняя |
| Риск data inconsistency | выше | ниже |
| Время загрузки ETL | быстрее | медленнее |
| Применимость в DWH | стандарт | редко |
Почему star выигрывает в DWH
1. Запросы проще
Bi-аналитик пишет SQL. JOIN product ON ... — один. vs два-три JOIN в snowflake.
2. Быстрее
DWH любит большие denormalized таблицы. Колоночные движки (ClickHouse, BigQuery) оптимизированы под широкие fact/dim.
3. BI-tools работают лучше
Tableau, Looker, Power BI плохо догоняют сложные joins. Star понятнее инструменту.
4. Storage уже не проблема
Дубли category в 10K продуктах — 10K раз слово «Electronics». Это секунды хранилища в 2026 году.
5. ETL проще
Загрузка одной denormalized таблицы проще, чем трёх связанных.
Когда snowflake имеет смысл
Очень большие dimensions с частыми обновлениями
Если в dimension 100 колонок и часто меняется — snowflake даёт контроль.
Regulatory compliance
Для финансовой отчётности иногда требуется нормализация (аудит, правила).
Шарируемые подDimensions
Если dim_geography используется в 5 fact-таблицах → выносим отдельно (это близко к snowflake).
Legacy-системы OLTP
В OLTP нормализация важна. Но это не DWH.
Гибрид: galaxy / constellation schema
Несколько fact-таблиц, разделяющих общие dimensions.
fact_orders ---+--- dim_date
|
fact_clicks ---+Несколько «звёзд», связанных через shared dimensions. Реальные DWH обычно такие.
Практика проектирования
Начать со star
Всегда сначала star. Если упрётесь в проблему — можно перейти к snowflake.
SCD2 для changing dimensions
Если dimension меняется (user переехал, product сменил цену) — SCD2 с valid_from/valid_to.
Широкие fact-таблицы
Включить в fact самые часто нужные колонки из dim через denormalization. Меньше JOIN на runtime.
Conformed dimensions
Общие dimensions между fact-таблицами. dim_date одна на все, не повторять.
На собесе
Вопрос: «Какая схема лучше?»
Хороший ответ:
- Star почти всегда (простота, скорость)
- Snowflake — если dimensions большие и часто меняются
- Важнее знать, когда применять SCD, чем идеологически выбирать
Вопрос: «В чём проблема snowflake?»
- Лишние JOIN → медленнее запросы
- BI-инструменты с ними хуже работают
- Типичная задача выражается через 5 JOIN вместо 2
Частые ошибки
Ошибка 1. Смешивать OLTP и DWH подходы
В OLTP-Postgres — 3NF нормализация. В DWH — star denormalized. Разные цели.
Ошибка 2. Делать snowflake из моды
«Нормализация — правильно» — принцип из 80-х. В DWH это вредит.
Ошибка 3. Star без SCD
Denormalized dim без обработки изменений → потеря истории.
Ошибка 4. Очень широкие fact-таблицы (100+ колонок)
Граница между полезной denormalization и бардаком. Здравый смысл важен.
Связанные темы
FAQ
Star или snowflake для аналитики?
Star в 95% случаев. Snowflake только при конкретных причинах.
Можно ли смешивать?
Да — galaxy / constellation schema. Часть dimensions денормализованы, часть нет.
Star — это про Kimball?
Да, Ralph Kimball — автор подхода. «Dimensional modeling» = star schema подход.
Snowflake лучше для data lake?
Data lake вообще обычно без жёсткой схемы (schema-on-read). Star/snowflake — для структурированного DWH.
Тренируйте data modelling — откройте тренажёр с 1500+ вопросами для собесов.