Skip to content
PПромтбук
RUEN
07Моделирование

3NF vs star vs One Big Table: когда что выбирать

Trade-offs read perf / write complexity / storage для OLTP, OLAP и аналитики. Как мигрировать между моделями без переписывания клиентов.

Помоги выбрать модель данных для workload: {{workload}}. Размер: {{data_size}}. Платформа: {{warehouse}}.

Три подхода

3NF (нормализация до третьей формы)

Каждый факт хранится в одном месте. Связи через FK.

  • Плюсы: нет аномалий обновления, минимум места, целостность через constraints.
  • Минусы: аналитический запрос требует 8 JOIN'ов, оптимизатор иногда ошибается.
  • Когда: OLTP, источник транзакций, любая запись > чтение в 10×. Postgres/MySQL.

Star schema (Kimball)

Денормализация на уровне измерений. Факт-таблицы тонкие, dim'ы плоские.

  • Плюсы: аналитические запросы простые (1 факт + N dims), BI-инструменты понимают, селективные индексы работают.
  • Минусы: требует ETL для поддержания, аномалии при обновлении dim надо разруливать SCD.
  • Когда: классическое DWH, BI-отчёты, mixed workload. Redshift, Synapse, Postgres.

One Big Table (OBT)

Полная денормализация: всё в одной wide-таблице с сотнями колонок.

  • Плюсы: zero JOIN'ов, колоночные движки сжимают эффективно, любой запрос — линейное сканирование.
  • Минусы: обновление атрибута dim — переписать миллионы строк, схема жёсткая, дубликат данных огромный.
  • Когда: аналитика на BigQuery/Snowflake/Clickhouse, immutable события (логи, телеметрия), append-only нагрузка.

Таблица решений

| Критерий | 3NF | Star | OBT | | Write QPS | Высокий | Средний | Низкий (batch) | | Read complexity | Высокая (много JOIN) | Средняя | Низкая | | Storage cost | Минимум | 2-3× | 5-20× | | Schema flexibility | Высокая | Средняя | Низкая (миграция = переписать) | | Аномалии обновления | Защищено | SCD управляет | Дубликаты | | Подходит для BI | Плохо | Идеально | Хорошо | | Подходит для ad-hoc | Плохо | Средне | Идеально |

Эвристики выбора

  • Write-heavy + транзакции → 3NF в OLTP
  • Read-heavy + регулярные отчёты → Star в DWH
  • Append-only events + ad-hoc analytics → OBT в колоночном движке
  • Mixed → 3NF source + Star/OBT marts через ELT

Trade-offs, о которых забывают

  • Колоночные движки меняют арифметику. JOIN дорогой, но сжатие OBT экономит I/O. Замерь, не теоретизируй.
  • SCD на OBT — кошмар. История через event-time + denorm snapshot колонки, без UPDATE.
  • Запись в OBT делается batch'ами через MERGE/INSERT OVERWRITE, не построчно.
  • 3NF в OLAP работает на маленьких объёмах (≤100GB), на больших — JOIN'ы выходят из RAM.

Migration patterns

3NF → Star:

  • Шаг 1: identify business processes (Kimball bus matrix)
  • Шаг 2: built marts as views поверх 3NF
  • Шаг 3: материализовать views по мере роста latency
  • Шаг 4: переключить клиентов; держать 3NF как source of truth

Star → OBT:

  • Шаг 1: SELECT fact.*, dim1.*, dim2.* FROM fact JOIN dims материализовать в новую таблицу
  • Шаг 2: pre-aggregate по самой частой грануляции
  • Шаг 3: версионировать схему (v1, v2 параллельно)
  • Шаг 4: deprecate star после миграции дашбордов

Anti-patterns

  • ❌ Денормализовать в OLTP «для скорости отчётов» — обновление одного customer.name пишет в 10M строк
  • ❌ Хранить OLAP-данные в 3NF без materialised views — каждый дашборд = пересчёт с диска
  • ❌ OBT на платформе с дорогим storage (Snowflake compute), хотя partition pruning не работает — счёт улетит
  • ❌ Сравнивать read perf 3NF vs Star на пустой БД — план меняется на реальных объёмах
  • ❌ Миграция «big bang» вместо параллельной работы — клиенты сломаются, откатываться некуда
К подразделу «Моделирование»
Похожие промты