Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Нормализация: как убрать опасные повторы
normalization

Нормализация: как убрать опасные повторы

Зависимости между данными, ошибки повторения и осознанное хранение итогов

Открыть лабораториюv1.1.0Запускается локально из публичного репозитория

Нормализация: как убрать опасные повторы

На прошлом уроке мы разнесли товары, пользователей и заказы по таблицам. Теперь разберём, почему такое разделение уменьшает число ошибок.

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

Пример одной слишком широкой таблицы

Представим таблицу, где в каждой строке заказа повторяются данные клиента и организации:

order_iduser_idemailorg_idorg_nameplan
1017anna@example.ru3Ромашкаpro
1027anna@example.ru3Ромашкаpro

Если организация сменит тариф, поле plan придётся менять во всех её заказах. Пропущенная строка сохранит старое значение, хотя речь идёт об одном факте.

Здесь действуют зависимости:

  • номер заказа определяет пользователя: order_id → user_id;
  • пользователь определяет организацию: user_id → org_id;
  • организация определяет свой тариф: org_id → plan.

Запись X → Y читается так: «для одного значения X возможно только одно значение Y». Это называется функциональной зависимостью.

Какие ошибки создают повторы

Повторение одного факта в разных строках приводит к трём типичным проблемам.

  • Ошибка обновления: тариф нужно изменить во многих заказах, и значения могут разойтись.
  • Ошибка добавления: новую организацию нельзя сохранить, пока у неё нет ни одного заказа.
  • Ошибка удаления: при удалении последнего заказа исчезают единственные сведения об организации.

Эти проблемы часто называют аномалиями обновления, вставки и удаления. Решение для примера — отдельные таблицы organizations, app_users и orders, связанные внешними ключами. Название и тариф организации тогда хранятся в одной строке organizations.

Нормальные формы простыми словами

Нормальная форма — набор правил, помогающий находить неправильные зависимости. Для начала достаточно понимать их смысл.

  1. Первая нормальная форма (1NF): в одной ячейке хранится одно значение, а повторяющиеся элементы становятся отдельными строками. Список товаров заказа лучше хранить в order_items, а не в столбцах product_1, product_2.
  2. Вторая нормальная форма (2NF): если ключ составной, остальные столбцы описывают весь ключ, а не только его часть. В позиции заказа количество относится к паре «заказ + товар».
  3. Третья нормальная форма (3NF): неключевой столбец не должен определяться другим неключевым столбцом. Тариф зависит от организации, поэтому ему не место в строке заказа.
  4. Нормальная форма Бойса — Кодда (BCNF): более строгое правило: левая часть любой значимой зависимости должна однозначно определять строку.

Не нужно заучивать названия перед практикой. Сначала спрашивайте: «Если факт изменится, в скольких местах его придётся исправить?»

Не всякое повторение ошибочно

В позиции заказа хранится unit_price — цена на момент покупки. В таблице товаров хранится текущая цена. Значения могли совпасть при создании заказа, но они отвечают на разные вопросы, поэтому это два разных факта.

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

Перед денормализацией нужно ответить:

  • какой запрос действительно медленный и как это измерено;
  • насколько свежим должен быть результат;
  • кто обновляет сохранённое значение;
  • как повторить обновление после сбоя;
  • как сравнить итог с исходными строками и исправить расхождение;
  • как удалить это усложнение, если оно перестанет помогать.

Периодическое сравнение производного значения с исходными данными называют сверкой (reconciliation). Только один механизм должен владеть обновлением: не стоит поручать одну сумму одновременно триггеру, приложению и фоновой задаче.

Массив или отдельная таблица

Массив подходит для небольшого набора простых значений без собственных свойств. Например, у записи могут быть метки ['new', 'gift'].

Если у элемента есть автор, дата, порядок, права или ссылка на другую таблицу, нужна таблица связи. Товар заказа имеет количество и цену, поэтому список идентификаторов товаров в массиве потерял бы важные сведения.

JSONB и массивы полезны, но не отменяют проектирование связей.

Практика

В лаборатории 03 вы начнёте с широкой таблицы заказов, выпишете зависимости и разделите её до 3NF. Затем добавите один сохранённый итог и SQL-запрос для его сверки.

После работы объясните своими словами:

  1. Какой факт повторялся в исходной таблице?
  2. Какая ошибка возникала при его изменении?
  3. Почему историческая цена заказа не считается ошибочным повтором?
  4. Кто отвечает за обновление добавленного итога?

Подробнее: ограничения и связи между таблицами.

Проверьте свои знания

Вопросы ещё не добавлены

Вопросы для этой подтемы ещё не добавлены.

Далее: Типы данных: какие значения можно хранить