Нормализация БД: шпаргалка для собеседования
Зачем аналитику знать нормализацию
На собесе аналитика — не самая частая тема, но для системных и бизнес-аналитиков обязательная. Плюс понимание помогает дизайнить аналитические хранилища и маркеты.
Основы: что такое нормализация
Нормализация — процесс разделения данных на несколько связанных таблиц, чтобы избежать:
- Избыточности — один факт хранится в нескольких местах.
- Аномалий обновления — меняем одно, надо обновить везде.
- Аномалий вставки/удаления — не можем добавить одно без другого.
1NF (первая нормальная форма)
Правило: в каждой ячейке — одно значение. Никаких списков.
Плохо:
| user_id | name | phones |
|---|---|---|
| 1 | Иван | '+79991234567, +79998765432' |
Хорошо:
| user_id | name |
|---|---|
| 1 | Иван |
| phone_id | user_id | phone |
|---|---|---|
| 1 | 1 | '+79991234567' |
| 2 | 1 | '+79998765432' |
2NF (вторая нормальная форма)
Правило: каждый не-ключевой атрибут зависит от всего первичного ключа, а не его части.
Применяется при составном ключе.
Плохо: (order_id, product_id) — ключ, а product_name зависит только от product_id:
| order_id | product_id | product_name | quantity |
|---|---|---|---|
| 1 | 10 | «Телефон» | 2 |
Хорошо: вынести product_name в отдельную таблицу products.
3NF (третья нормальная форма)
Правило: не-ключевые атрибуты не зависят друг от друга (только от ключа).
Плохо: city_name зависит от city_id, а не от user_id:
| user_id | name | city_id | city_name |
|---|---|---|---|
| 1 | Иван | 77 | Москва |
Хорошо: отдельная таблица cities.
Попробовать силы на подобных вопросах проще всего в тренажёре Карьерник — прямо в Telegram, без регистрации через сайт.
BCNF (Boyce-Codd)
Более строгая 3NF. На практике 3NF ≈ BCNF для простых схем.
Денормализация — обратный процесс
В аналитических хранилищах (DWH, data lake) специально не нормализуют:
- Reading > Writing: в OLTP мы часто INSERT/UPDATE — надо избежать аномалий. В OLAP чаще читаем — денормализация ускоряет.
- JOIN дорого: 10 JOIN-ов на миллионах строк — медленно. Одна широкая таблица — быстро.
- Звёздная схема: фактовая таблица + dimension-таблицы. Факты денормализованы, dimensions — нормализованы.
Пример денормализованного fact-таблицы:
| order_id | user_id | user_name | city | product_id | product_name | category | price |
|---|
Все данные в одной таблице. Аналитические запросы быстрые, но:
- Если city меняется → надо обновлять во всех строках.
- Избыточность в разы — гигабайты «повторений».
В современной аналитике это ОК — память дешёвая, скорость важнее.
Когда нормализовывать
- OLTP-системы: банки, e-commerce checkouts, bookings.
- Финансовые транзакции.
- Данные, которые часто меняются.
- Компактность критична (встройка, IoT).
Когда денормализовывать
- DWH, data marts.
- Аналитические дашборды.
- Отчётность.
- OLAP-системы.
- Когда JOIN ≥ 5 таблиц делает запрос медленным.
Звёздная и снежинка
Звёздная схема (star schema)
- Одна центральная fact-таблица (orders, events).
- Несколько dimension-таблиц (users, products, dates).
- Dimensions денормализованы (всё в одной таблице).
Снежинка (snowflake)
- Как звезда, но dimensions нормализованы.
- Products → categories → category_groups.
- Больше JOIN-ов, но меньше избыточности.
Для быстрой аналитики — star. Для гибкости — snowflake.
Пройти 30–50 задач по теме за вечер можно в Telegram-тренажёре. Это то, что отличает «знаю» от «уверенно отвечу на собесе».
Типичные ошибки
1. Переmormalize в OLTP
5NF для малой базы — лишняя работа. 3NF обычно достаточно.
2. Не денормализовывать в DWH
Строгая 3NF в аналитическом хранилище убивает производительность.
3. Хранить списки в ячейках
Comma-separated IDs ('1,2,3') — кошмар для поиска. Всегда разделять в отдельную таблицу.
4. Забытый PK / FK
Без PK индексы не строятся. Без FK нарушения ссылочной целостности.
Собеседование: 10 вопросов
1. Что такое нормализация?
Процесс разделения данных, чтобы избежать избыточности и аномалий.
2. Разница между 2NF и 3NF?
2NF — убирает зависимость от части ключа. 3NF — убирает зависимость между не-ключевыми атрибутами.
3. Когда денормализовывать?
В аналитике, OLAP, DWH. Когда чтений сильно больше, чем записей, и JOIN медленны.
4. Что такое PK и FK?
PK — первичный ключ (уникальный идентификатор строки). FK — внешний ключ (ссылка на PK другой таблицы).
5. Звёздная или снежинка для DWH?
Обычно звёздная — быстрее. Снежинка когда dimensions очень большие и избыточность критична.
6. Как избежать аномалии обновления?
Нормализация 3NF. Данные хранятся в одном месте → обновление одной строки достаточно.
7. Можно ли хранить JSON в реляционной БД?
Можно (jsonb в PostgreSQL, JSON в MySQL). Но для часто запрашиваемых полей — разбить на нормальную структуру быстрее и надёжнее.
8. Индексы и нормализация — связаны?
Да. Нормализованная схема обычно требует больше JOIN — нужны индексы на FK. Денормализованная — меньше JOIN, но индексы на WHERE-поля.
9. OLTP vs OLAP — разница в нормализации?
OLTP — высокая нормализация (3NF+). OLAP — денормализация (звёздная схема).
10. Что такое 6NF?
Очень редкое применение — для temporal-данных. На практике в аналитике не встречается.
Как тренироваться
Нормализация — теоретическая тема. Практика: придумывайте схемы для реальных случаев (e-commerce, соцсети, маркетплейс) и дискутируйте в команде.
Совет: на собесе, обсуждая нормализацию, всегда говорите про trade-off. «3NF для транзакционной системы, но для DWH денормализуем». Это показывает зрелость.
Читайте также
FAQ
Нужно ли аналитику знать 5NF?
Нет. 3NF + звёздная схема — хватает на 99% собесов.
Почему в аналитических системах не нормализуют?
Оптимизация для чтения. JOIN 10 таблиц на миллиардах строк медленный. Широкая таблица с повторами данных — быстрый.
Как понять, что данные денормализованы правильно?
Если JOIN-ы не нужны для типичных запросов, запросы работают < 5 сек, и обновления делаются в ETL (не в реальном времени) — всё ок.
dbt и нормализация?
dbt обычно используется для денормализации: из normalised source-таблиц делать aggregated/denormalised marts для аналитики.