Объясните механизм, при котором отношение проходит проверку третьей нормальной формы, но нарушает нормальну...

Объясните механизм, при котором отношение проходит проверку третьей нормальной формы, но нарушает нормальную форму Бойса—Кодда.

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

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

Исторический контекст

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

Нормальная форма Бойса—Кодда усиливает это правило: она устраняет случаи, которые могут оставаться допустимыми в третьей нормальной форме из-за особого положения ключевых атрибутов. Поэтому отношение может соответствовать 3НФ, но всё ещё содержать избыточность, связанную с пересекающимися кандидатными ключами.

Постановка проблемы

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

Тогда существуют зависимости:

  • студент, курс → преподаватель;
  • студент, преподаватель → курс;
  • преподаватель → курс.

Кандидатными ключами являются студент—курс и студент—преподаватель. При этом преподаватель сам по себе не является суперключом, поскольку один преподаватель связан с записями многих студентов.

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

Подробное решение

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

Для НФБК этого недостаточно. Её условие строже: левая часть каждой нетривиальной функциональной зависимости обязана быть суперключом. В зависимости преподаватель → курс преподаватель не является суперключом, поэтому отношение нарушает НФБК.

Практическое разбиение выносит зависимость преподаватель → курс в отдельное отношение:

CREATE TABLE instructor_course ( instructor_id INTEGER PRIMARY KEY, course_id INTEGER NOT NULL ); CREATE TABLE enrollment ( student_id INTEGER NOT NULL, instructor_id INTEGER NOT NULL, PRIMARY KEY (student_id, instructor_id), FOREIGN KEY (instructor_id) REFERENCES instructor_course (instructor_id) );

В instructor_course детерминант преподаватель является первичным ключом, поэтому зависимость корректно представлена. В enrollment хранится только связь студента с преподавателем, а курс получается через соединение.

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

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

Ситуация из практики

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

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

Выбрали отдельную таблицу назначения преподавателя курсу и таблицу регистраций, ссылающуюся на это назначение. Решение было обосновано тем, что правило преподаватель → курс является самостоятельным фактом предметной области и должно храниться один раз. После этого изменение назначения выполнялось одной операцией, а противоречивые строки перестали возникать.

Что кандидаты часто упускают

  1. Всегда ли нарушение НФБК означает нарушение третьей нормальной формы?

Нет. НФБК строже 3НФ, поэтому возможна схема, которая соответствует 3НФ, но не соответствует НФБК. Именно это происходит, когда детерминант не является суперключом, а правая часть зависимости является ключевым атрибутом.

  1. Почему в проверке нужно анализировать все кандидатные ключи, а не только первичный ключ?

Первичный ключ — это только один выбранный кандидатный ключ. Нормальные формы определяются логическими зависимостями и всеми кандидатными ключами, а не тем, какой ключ назначен первичным. Если учитывать только первичный ключ, можно не заметить, что другой набор атрибутов также уникален и участвует в зависимости, создающей нарушение НФБК.

  1. Достаточно ли разбиения по зависимости, чтобы схема автоматически стала корректной?

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