Нормализация базы данных — 1NF, 2NF, 3NF простыми словами

Коротко

Нормализация — это процесс организации таблиц в базе данных так, чтобы данные не дублировались и не противоречили друг другу. На практике выделяют три основных нормальных формы: 1NF, 2NF, 3NF. Аналитику важно понимать нормализацию, чтобы разбираться в структуре продуктовых баз и объяснять, почему аналитические хранилища часто строят наоборот — денормализованно.

Зачем нужна нормализация

Представьте таблицу заказов, где в каждой строке дублируются имя клиента, его email и адрес. Клиент меняет email — нужно обновить сотни строк. Забыли одну — данные противоречат друг другу. Это называется аномалиями обновления.

Нормализация решает три проблемы:

  • Аномалия обновления — одно изменение требует обновления множества строк.
  • Аномалия вставки — нельзя добавить данные, пока нет связанной записи (например, нельзя добавить нового клиента без заказа).
  • Аномалия удаления — удаляя заказ, теряем информацию о клиенте.

На собеседованиях нормальные формы спрашивают на уровне понимания: зачем это нужно, как выглядит 1NF/2NF/3NF, и почему в аналитике часто используют денормализацию. Писать SQL для нормализации обычно не просят — достаточно объяснить на примере таблиц.

Первая нормальная форма (1NF)

Правило: каждая ячейка таблицы содержит одно атомарное значение. Никаких списков, массивов или вложенных таблиц.

До нормализации:

order_id customer products
1 Иванов Ноутбук, Мышь
2 Петрова Клавиатура
3 Иванов Монитор, Кабель, Мышь

Столбец products хранит несколько значений через запятую. Нельзя нормально фильтровать, агрегировать, джойнить по отдельным товарам.

После приведения к 1NF:

order_id customer product
1 Иванов Ноутбук
1 Иванов Мышь
2 Петрова Клавиатура
3 Иванов Монитор
3 Иванов Кабель
3 Иванов Мышь

Каждая ячейка — одно значение. Теперь можно считать количество заказов по товару, фильтровать по конкретному продукту и строить индексы по столбцу product.

Вторая нормальная форма (2NF)

Правило: таблица в 1NF + каждый неключевой столбец зависит от всего первичного ключа целиком, а не от его части.

2NF актуальна для таблиц с составным первичным ключом. Если ключ — одно поле, таблица в 1NF автоматически в 2NF.

Проблема — частичная зависимость:

order_id product_id product_name quantity
1 101 Ноутбук 1
1 102 Мышь 2
2 101 Ноутбук 1

Первичный ключ — (order_id, product_id). Столбец product_name зависит только от product_id, а не от всего ключа. Если переименовать товар — нужно обновить все строки.

После приведения к 2NF — разделяем на две таблицы:

Таблица order_items:

order_id product_id quantity
1 101 1
1 102 2
2 101 1

Таблица products:

product_id product_name
101 Ноутбук
102 Мышь

Название товара хранится в одном месте. Изменение — одна строка.

Третья нормальная форма (3NF)

Правило: таблица в 2NF + нет транзитивных зависимостей. Неключевой столбец не должен зависеть от другого неключевого столбца.

Проблема — транзитивная зависимость:

order_id customer_id customer_name customer_city
1 10 Иванов Москва
2 11 Петрова Казань
3 10 Иванов Москва

Первичный ключ — order_id. Столбцы customer_name и customer_city зависят от customer_id, а не напрямую от order_id. Это транзитивная зависимость: order_id -> customer_id -> customer_name.

После приведения к 3NF:

Таблица orders:

order_id customer_id
1 10
2 11
3 10

Таблица customers:

customer_id customer_name customer_city
10 Иванов Москва
11 Петрова Казань

Теперь данные о клиенте хранятся в одном месте. Изменение города — обновление одной строки в customers.

BCNF

Нормальная форма Бойса-Кодда (BCNF) — усиленная версия 3NF. Требование: каждая нетривиальная функциональная зависимость должна исходить от суперключа. На практике разница между 3NF и BCNF проявляется редко — только в таблицах с несколькими перекрывающимися составными ключами.

На собеседованиях аналитиков BCNF спрашивают нечасто. Достаточно знать, что она существует и является «строгой версией 3NF». Если спросили — ответьте одним предложением и переходите к денормализации.

Денормализация для аналитики

Нормализация хороша для транзакционных (OLTP) баз: меньше дублирования, проще обновления. Но аналитические запросы — это совсем другая история. Аналитику нужно:

  • Читать миллионы строк, а не обновлять по одной.
  • Минимизировать джойны — каждый JOIN замедляет тяжёлый запрос.
  • Быстро агрегировать данные по разным срезам.

Поэтому аналитические хранилища (DWH) строят денормализованно:

  • Схема «звезда» (Star Schema) — центральная таблица фактов (например, fact_orders) окружена таблицами измерений (dim_customers, dim_products, dim_dates). Факты хранят числовые метрики и ключи измерений. Один уровень джойнов вместо каскада.
  • Плоские таблицы (flat tables) — все данные собраны в одну широкую таблицу. Никаких джойнов. Максимальная скорость чтения за счёт дублирования.
  • Колоночные БД (ClickHouse, BigQuery, Redshift) — оптимизированы под чтение столбцов, а не строк. Денормализация здесь работает особенно хорошо.

Аналитик должен понимать оба подхода: нормализация — как устроена продуктовая база, денормализация — как устроено хранилище, из которого он строит отчёты.

Вопросы с собеседований

Что такое нормализация и зачем она нужна? — Нормализация — процесс разделения таблиц для устранения избыточности данных и аномалий обновления, вставки, удаления. Каждый факт хранится в одном месте, что упрощает поддержку и гарантирует целостность данных.

Объясните разницу между 1NF, 2NF и 3NF. — 1NF: атомарные значения в каждой ячейке, никаких списков. 2NF: нет частичных зависимостей от составного ключа. 3NF: нет транзитивных зависимостей — неключевые столбцы зависят только от первичного ключа, а не от других неключевых столбцов.

Почему аналитические базы данных часто денормализованы? — Аналитические запросы читают большие объёмы данных и агрегируют по разным срезам. Денормализация сокращает количество джойнов, ускоряет чтение и упрощает запросы. Дублирование данных — осознанный компромисс ради скорости.

Что такое схема «звезда»? — Модель данных для хранилища: центральная таблица фактов (транзакции, события) окружена таблицами измерений (клиенты, товары, даты). Один уровень джойнов. Оптимизирована для аналитических запросов и инструментов BI.

Когда нормализация вредна? — Когда приоритет — скорость чтения, а не целостность записи. В OLAP-системах, отчётных витринах и дашбордах нормализация создаёт лишние джойны без пользы. Также нормализация может быть избыточна для маленьких справочников или логов, которые только записываются и читаются.


Потренируйтесь решать задачи — откройте тренажёр с 1500+ вопросами для подготовки к собеседованиям аналитиков.

FAQ

Нужно ли аналитику уметь нормализовать базу данных?

Проектировать схему с нуля — задача инженера данных или DBA. Но аналитик должен понимать, почему таблицы связаны через ключи, откуда берутся джойны и почему в продуктовой базе данные о клиенте лежат отдельно от заказов. На собеседовании достаточно объяснить 1NF/2NF/3NF на примерах и аргументировать, когда денормализация оправдана.

Какую нормальную форму считают достаточной?

В большинстве продуктовых баз останавливаются на 3NF. Дальнейшая нормализация (BCNF, 4NF, 5NF) даёт минимальный выигрыш при заметном усложнении структуры. На собеседованиях тоже редко заходят дальше третьей формы.

Как нормализация связана с производительностью SQL-запросов?

Нормализованная база требует больше джойнов — это может замедлять тяжёлые аналитические запросы. Но для транзакционных операций (вставка, обновление) нормализация ускоряет работу: меньше данных для записи, меньше блокировок. Правильные индексы помогают компенсировать стоимость джойнов.

Где потренировать SQL-запросы с джойнами по нормализованным таблицам?

В тренажёре Карьерник есть задачи на джойны, агрегации и подзапросы по реалистичным нормализованным схемам. Посмотреть формат вопросов можно в примерах.