0Pricing
Coding Interview Prep · Урок

Нормализация до третьей нормальной формы

Первая, вторая и третья нормальные формы и устраняемые ими аномалии

«Нормализация до третьей нормальной формы» — бесплатный урок Coding Interview Prep на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Coding Interview Prep, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Coding Interview Prep содержит 4 уроков всего.

Почему интервьюеры спрашивают о нормализации

Нормализация — фундаментальный принцип моделирования баз данных, и интервьюеры используют этот вопрос, чтобы проверить, понимаете ли Вы, как обеспечивается целостность данных на уровне проектирования. Обычно вопрос звучит так: «Что такое нормализация и почему она важна?»

Нормализация — это процесс организации столбцов и таблиц, направленный на уменьшение избыточности и предотвращение аномалий обновления, вставки и удаления. Каждая нормальная форма (1NF, 2NF, 3NF) добавляет более строгое правило.

В хорошем ответе нужно назвать аномалии, которые устраняет нормализация, а не просто воспроизвести учебниковые определения.

Три аномалии

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

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

Если Вы умеете находить эти аномалии в примерной таблице, Вы сможете обосновать каждый шаг нормализации.

Исходная ненормализованная таблица

Вот классический пример с собеседования: одна широкая таблица, в которой смешаны заказы, клиенты и товары. Обратите внимание на повторяющиеся адреса электронной почты клиентов и цены товаров в разных строках. Именно здесь возникают аномалии.

На собеседовании Вам нужно последовательно привести эту таблицу к 3NF, объясняя каждое разделение.

-- Unnormalized: everything in one table
CREATE TABLE orders_flat (
  order_id     INT,
  customer_id  INT,
  customer_email VARCHAR(255),
  product_id   INT,
  product_name VARCHAR(100),
  unit_price   DECIMAL(10,2),
  quantity     INT
);

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

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

Таблица нарушает 1NF, если в столбце хранится список через запятую, например 'phone1, phone2', или если у Вас есть столбцы product1, product2, product3.

Решение: поместить каждое значение в отдельную строку. Интервьюер ожидает услышать: «атомарные значения, отсутствие повторяющихся групп и ключ, идентифицирующий каждую строку».

-- Violates 1NF: a list inside one column
-- phones = '555-1111, 555-2222'

-- 1NF fix: one phone per row
CREATE TABLE customer_phone (
  customer_id INT,
  phone       VARCHAR(20),
  PRIMARY KEY (customer_id, phone)
);

Функциональные зависимости

Чтобы объяснить 2NF и 3NF, необходимо использовать термин функциональная зависимость. Запись A -> B означает «A определяет B»: для каждого значения A существует ровно одно значение B.

В нашей таблице заказов:

  • customer_id -> customer_email
  • product_id -> product_name, unit_price
  • order_id, product_id -> quantity

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

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

2NF применяется, когда первичный ключ является составным. Она запрещает неключевому столбцу зависеть только от части ключа (это называется частичной зависимостью).

Ключом строки заказа является (order_id, product_id). Однако product_name и unit_price зависят только от product_id, а не от полного ключа. Это частичная зависимость, поэтому таблица нарушает 2NF.

Решение: перенести атрибуты товара в таблицу products, ключом которой является product_id.

CREATE TABLE products (
  product_id   INT PRIMARY KEY,
  product_name VARCHAR(100),
  unit_price   DECIMAL(10,2)
);

CREATE TABLE order_items (
  order_id   INT,
  product_id INT,
  quantity   INT,
  PRIMARY KEY (order_id, product_id),
  FOREIGN KEY (product_id) REFERENCES products(product_id)
);

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

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

Предположим, что таблица orders содержит customer_id и customer_email. В таком случае order_id -> customer_id -> customer_email. Адрес электронной почты зависит от ключа только через customer_id, то есть транзитивно.

Решение: выделить клиентов в отдельную таблицу. Теперь неключевые столбцы каждой таблицы зависят только от её ключа.

CREATE TABLE customers (
  customer_id    INT PRIMARY KEY,
  customer_email VARCHAR(255)
);

CREATE TABLE orders (
  order_id    INT PRIMARY KEY,
  customer_id INT,
  FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

Правило для запоминания в одну строку

Интервьюеры любят кандидатов, которые могут сформулировать суть 3NF одним предложением. Классическая формулировка:

«Каждый неключевой столбец должен зависеть от ключа, всего ключа и ничего, кроме ключа».

  • Ключ -> 1NF (ключ существует, значения атомарны).
  • Весь ключ -> 2NF (нет частичной зависимости).
  • Ничего, кроме ключа -> 3NF (нет транзитивной зависимости).

Эта одна строка позволяет при необходимости восстановить все три формы.

BCNF: дополнительный вопрос

Внимательный интервьюер может спросить о нормальной форме Бойса — Кодда (BCNF) — более строгом варианте 3NF.

BCNF требует, чтобы для каждой функциональной зависимости X -> Y значение X было суперключом. 3NF допускает редкое исключение, когда зависимый атрибут является частью потенциального ключа; BCNF устраняет и это исключение.

На практике нарушения BCNF встречаются нечасто, но если Вы назовёте эту форму и скажете: «BCNF — это 3NF без исключений для ключевых атрибутов», Вы продемонстрируете глубокое понимание темы.

Когда NOT следует нормализовать

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

Осознанная денормализация допустима, если:

  • рабочая нагрузка в основном связана с чтением, а соединения стали узким местом;
  • Вы создаёте аналитический слой или слой отчётности (схемы «звезда» рассматриваются далее);
  • Вы можете поддерживать избыточную копию в синхронизированном состоянии (с помощью триггеров, ETL или материализованных представлений).

Скажите: «Нормализуйте данные для обеспечения целостности OLTP; осознанно денормализуйте их ради скорости чтения в OLAP».

Разбор у доски

Соберём всё вместе. На реальном собеседовании, получив неструктурированную таблицу:

  • назовите потенциальный ключ и перечислите функциональные зависимости;
  • проверьте атомарность и наличие повторяющихся групп (1NF);
  • если ключ составной, проверьте наличие частичных зависимостей (2NF);
  • проверьте зависимости между неключевыми столбцами (3NF);
  • нарисуйте получившиеся таблицы с первичными и внешними ключами.

Именно умение вслух объяснять эти шаги оценивает интервьюер.

Быстрая проверка

Проверьте, насколько хорошо Вы усвоили нормальные формы.

Итоги: нормализация до 3NF

Теперь Вы можете полностью ответить на типичный вопрос о нормализации на собеседовании:

  • Нормализация устраняет аномалии обновления, вставки и удаления, сокращая избыточность.
  • 1NF: атомарные значения, отсутствие повторяющихся групп.
  • 2NF: отсутствие частичной зависимости от составного ключа.
  • 3NF: отсутствие транзитивной зависимости (между неключевыми столбцами).
  • Формулировка для запоминания: «ключ, весь ключ и ничего, кроме ключа».
  • BCNF ужесточает требования 3NF; денормализацию следует осознанно применять для аналитики с преобладанием чтения.

Часто задаваемые вопросы

Урок «Нормализация до третьей нормальной формы» бесплатный?

Да — полный текст урока «Нормализация до третьей нормальной формы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Coding Interview Prep, подпишись на CoddyKit PRO. Курс Coding Interview Prep содержит 4 уроков всего.

Чему я научусь в уроке «Нормализация до третьей нормальной формы»?

Первая, вторая и третья нормальные формы и устраняемые ими аномалии Ты практикуешь Coding Interview Prep с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Coding Interview Prep?

Предыдущий опыт не требуется. Coding Interview Prep на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Нормализация до третьей нормальной формы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Coding Interview Prep?

Да. Каждый урок Coding Interview Prep включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Нормализация до третьей нормальной формы
  2. ER-моделирование и кардинальность связей
  3. Звёздная схема и проектирование хранилищ данных
  4. Полный набор задач для пробного собеседования
← Назад к Coding Interview Prep