Нормализация БД: функциональные зависимости
Фундаментальные основы реляционной теории: математический аппарат функциональных зависимостей, аксиоматика Армстронга, алгоритм вычисления замыкания атрибутов, поиск потенциальных ключей и каноническая минимизация схемы.
1. Почему проектировщику необходима нормализация?
Создание базы данных без строгого математического анализа часто приводит к объединению множества разнородных атрибутов в одну «универсальную» таблицу. Рассмотрим наивную структуру базы данных компании, где в едином отношении хранятся сведения о сотрудниках, их отделах и проектных ролях:
Такой подход порождает четыре классические аномалии реляционных баз данных:
| Вид аномалии | В чем проявляется дефект | Практический пример разрушения целостности |
|---|---|---|
| Избыточность данных (Redundancy) | Одни и те же факты дублируются в сотнях и тысячах строк. | Если в отделе 50 сотрудников, то телефон и название отдела будут скопированы 50 раз. Это приводит к перерасходу дискового пространства и памяти буферного пула. |
| Аномалия обновления (Update Anomaly) | Изменение одного свойства реального объекта требует изменения множества записей. | При смене телефонного номера отдела его необходимо обновить во всех 50 строках. Если сервер оборвет транзакцию на 25-й строке, база данных окажется в противоречивом состоянии. |
| Аномалия вставки (Insertion Anomaly) | Невозможность внести информацию об одной сущности без фиктивного создания другой. | Мы не можем зарегистрировать новый «Отдел инноваций», пока в него не нанят хотя бы один реальный сотрудник с конкретным EmpID (если EmpID входит в первичный ключ). |
| Аномалия удаления (Deletion Anomaly) | Удаление одной записи приводит к непреднамеренной потере других независимых данных. | Если увольняется единственный сотрудник отдела, то вместе с кортежем сотрудника удаляется вся информация о существовании самого отдела и его телефоне. |
2. Понятие и классификация функциональных зависимостей (ФЗ)
2.1. Формальное определение
Пусть R(U) — схема отношения, где U — совокупность всех атрибутов. Пусть X и Y — произвольные подмножества атрибутов (X ⊆ U, Y ⊆ U).
t₁[X] = t₂[X] ⟹ t₁[Y] = t₂[Y]
Множество X называют детерминантом (определяющим набором), а Y — зависимой частью.
X → Y — это семантическое ограничение предметной области, а не сиюминутное свойство загруженных данных! Нельзя просто взглянуть на текущую выборку из 5 строк и объявить, что если у всех разные имена, то Имя → Паспорт. ФЗ задается бизнес-логикой и правилами реального мира.
2.2. Классификация функциональных зависимостей
- Тривиальная зависимость: Правая часть полностью содержится в левой:
Y ⊆ X.
Пример:{Паспорт, ФИО} → {ФИО}. Такая зависимость тривиально истинна всегда, так как зная набор данных, мы всегда знаем его составную часть. - Нетривиальная зависимость: Правая часть содержит хотя бы один атрибут, отсутствующий в детерминанте:
Y ⊈ X.
Пример:{НомерСчета} → {Баланс, Валюта}. - Полная функциональная зависимость: Атрибут
Yзависит от составного детерминантаXв целом, но не зависит ни от одной его части.
Пример: Оценка студента зависит от пары{СтудентID, ПредметID} → Оценка. Отдельно отСтудентIDили отПредметIDоценка не зависит. - Частичная функциональная зависимость: Атрибут зависит не от всего составного ключа, а лишь от некоторой его части.
Пример: В отношении с ключом{СтудентID, ПредметID}зависимостьСтудентID → НомерГруппыявляется частичной. Наличие частичных зависимостей неключевых полей от первичного ключа нарушает Вторую нормальную форму (2НФ). - Транзитивная функциональная зависимость: Зависимость вида
X → Z, опосредованная промежуточным наборомY: еслиX → YиY → Z, причем обратной зависимостиY ↛ Xне существует, аZне входит вX ∪ Y.
Пример:ТабельныйНомер → НомерОтдела, аНомерОтдела → ТелефонОтдела. ЗависимостьТабельныйНомер → ТелефонОтделаявляется транзитивной. Наличие транзитивных зависимостей неключевых полей нарушает Третью нормальную форму (3НФ).
3. Аксиомы Армстронга и матрица применения правил вывода
В 1974 году Уильям Армстронг доказал, что любая верная для заданной схемы функциональная зависимость может быть выведена из исходного набора зависимостей с помощью всего трех базовых аксиом. Эта система аксиом является корректной (все выводимые зависимости действительно выполняются) и полной (любая истинная зависимость может быть выведена).
3.1. Базовые аксиомы
- Рефлексивность (Reflexivity): Если
Y ⊆ X, тоX → Y. В частности,X → X. - Пополнение (Augmentation): Если
X → Y, то для любого множества атрибутовZверно:XZ → YZ(а такжеXZ → Y). - Транзитивность (Transitivity): Если
X → YиY → Z, тоX → Z.
3.2. Матрица применения правил вывода Армстронга на практике
Для ускорения логического анализа проектировщики используют вспомогательные производные правила. Матрица ниже иллюстрирует, когда и какое правило следует применять в инженерных расчетах:
| Инженерная задача | Применяемое правило | Исходные условия | Результат вывода | Практический пример |
|---|---|---|---|---|
| Склеить несколько правых частей с общим детерминантом | Объединение (Union) | X → Y и X → Z |
X → YZ |
Паспорт → ФИО и Паспорт → ДатаРождения ⟹ Паспорт → {ФИО, ДатаРождения}. |
| Разделить сложную правую часть на независимые атомарные ФЗ | Декомпозиция (Decomposition) | X → YZ |
X → Y и X → Z |
АвтомобильID → {Марка, Цвет} ⟹ АвтомобильID → Марка и АвтомобильID → Цвет. |
| Заменить промежуточный атрибут в составном детерминанте | Псевдотранзитивность (Pseudotransitivity) | X → Y и YZ → W |
XZ → W |
Если СтудентID → Группа и {Группа, Предмет} → Преподаватель, то {СтудентID, Предмет} → Преподаватель. |
| Параллельно скомбинировать две независимые зависимости | Композиция (Composition) | X → Y и Z → W |
XZ → YW |
ЗаказID → Дата и ТоварID → Цена ⟹ {ЗаказID, ТоварID} → {Дата, Цена}. |
| Накопить атрибуты в правой части через транзитивный мост | Накопление (Accumulation) | X → YZ и Z → W |
X → YZW |
Договор → {Клиент, Город} и Город → Регион ⟹ Договор → {Клиент, Город, Регион}. |
4. Алгоритм нахождения замыкания множества атрибутов X+
Замыканием множества атрибутов X относительно множества зависимостей F (обозначается X⁺) называется совокупность всех атрибутов схемы, которые функционально определяются набором X на основе правил вывода: X⁺ = {A ∈ U | F ⊢ X → A}.
Вычисление замыкания — ключевой алгоритм всей реляционной теории. С его помощью проверяется истинность любой произвольной ФЗ X → Y (достаточно проверить, входит ли Y ⊆ X⁺) и определяются первичные ключи отношений.
Пошаговый псевдокод
Вход: Набор атрибутов X, множество зависимостей F.
Выход: Множество X⁺.
Шаг 1. Инициализировать результат исходным набором:
X⁺ := X;
Шаг 2. В цикле просматривать все зависимости A → B из F:
ЕСЛИ левая часть A является подмножеством X⁺ (A ⊆ X⁺),
ТО добавить атрибуты правой части B к результату:
X⁺ := X⁺ ∪ B;
Шаг 3. Повторять шаг 2 до тех пор, пока на очередной итерации
множество X⁺ перестанет пополняться новыми атрибутами (достигнута неподвижная точка).
Шаг 4. Вернуть X⁺.
Пошаговый пример трассировки 1
Дано отношение со схемой R(A, B, C, D, E, F) и множеством зависимостей:
Задача: Вычислить замыкание атрибутов {B, E}⁺.
| Шаг итерации | Проверяемая ФЗ | Условие применимости (LHS ⊆ Текущее) | Результат добавления в X⁺ |
|---|---|---|---|
| Старт | — | Инициализация | {B, E} |
| Итерация 1 | E → C |
{E} ⊆ {B, E} (ИСТИНА) |
Добавляем C: {B, E, C} |
| Итерация 1 | BC → D |
{B, C} ⊆ {B, E, C} (ИСТИНА) |
Добавляем D: {B, E, C, D} |
| Итерация 1 | D → A |
{D} ⊆ {B, E, C, D} (ИСТИНА) |
Добавляем A: {B, E, C, D, A} |
| Итерация 2 | A → B |
{A} ⊆ {A, B, C, D, E} (ИСТИНА) |
B уже в наборе: {A, B, C, D, E} |
| Итерация 2 | Оставшиеся ФЗ | Новых атрибутов не дают | {A, B, C, D, E} |
Итог: {B, E}⁺ = {A, B, C, D, E}. Атрибут F в замыкание не вошел, следовательно {B, E} не является суперключом.
5. Определение потенциальных ключей отношения
Иерархия ключевых понятий строится следующим образом:
- Суперключ (Superkey): Любой набор атрибутов
K, чье замыкание включает все атрибуты отношения:K⁺ = U. - Потенциальный (кандидатный) ключ (Candidate Key): Минимальный суперключ. Это означает, что
K⁺ = U, но если убрать изKхотя бы один атрибут, то замыкание перестанет покрывать всё отношение. - Первичный ключ (Primary Key): Один из потенциальных ключей, официально назначенный проектировщиком для связывания таблиц через внешние ключи.
Эвристический алгоритм поиска ключей: Метод L-R-B-N
Полный перебор всех 2ⁿ подмножеств атрибутов неэффективен. Профессиональный проектировщик классифицирует атрибуты на 4 группы по их участию в ФЗ F:
| Группа | Участие во множестве F | Правило для ключа |
|---|---|---|
| L (Left only) | Встречается только слева | Обязательно входит в абсолютно каждый потенциальный ключ отношения. |
| R (Right only) | Встречается только справа | Никогда не входит ни в один потенциальный ключ (он зависим). |
| N (Neither) | Вообще не встречается в ФЗ | Обязательно входит в абсолютно каждый потенциальный ключ. |
| B (Both) | Встречается и слева, и справа | Может входить или не входить. Перебираются только комбинации (L ∪ N) ∪ B'. |
- Определить базовое ядро
Core = L ∪ N. - Вычислить
(Core)⁺. Если(Core)⁺ = U, тоCore— единственный потенциальный ключ! Поиск завершен. - Если
(Core)⁺ ⊂ U, поочередно добавляем кCoreпо одному атрибуту из группыB, затем по два, отсекая надмножества уже найденных ключей.
6. Каноническое (минимальное) покрытие ФЗ (Minimal Cover)
В реальных проектах множество бизнес-правил может содержать избыточные зависимости и лишние поля в составных ключах. Минимальное покрытие F_c для множества зависимостей F — это эквивалентный набор ФЗ минимального размера без логического балласта.
Три требования к минимальному покрытию:
- Каноническая правая часть (Singleton RHS): Каждая зависимость имеет ровно один атрибут справа:
X → A. - Неизбыточность детерминантов (No extraneous LHS attributes): Ни из одной левой части нельзя удалить атрибут без потери выводимости.
- Неизбыточность зависимостей (No redundant FDs): Ни одну ФЗ нельзя удалить целиком без потери выводимости.
Пошаговый пример минимизации покрытия
Дано отношение R(A, B, C, D) и исходное множество зависимостей:
Шаг 1. Расщепление правых частей (Singleton RHS)
Зависимость AB → CD расщепляем по правилу декомпозиции на AB → C и AB → D:
Удаляем явный дубликат AB → D: F₁ = { AB → C, AB → D, A → B, C → D, D → C }.
Шаг 2. Проверка и устранение посторонних атрибутов слева (LHS)
Проверим составной детерминант AB → C. Можно ли удалить B (проверяем A → C)?
Вычисляем замыкание {A}⁺ во множестве F₁:
{A}⁺: по A → B получаем {A, B}; по AB → C получаем {A, B, C}.
Так как C ∈ {A}⁺, атрибут B в детерминанте AB → C является посторонним (избыточным)! Заменяем AB → C на A → C.
Аналогично для AB → D: D ∈ {A}⁺, заменяем на A → D.
Текущее множество:
Шаг 3. Устранение избыточных зависимостей
Проверяем каждую зависимость на возможность вывода из остальных:
- Проверяем
A → D: удалим ее и проверим{A}⁺в оставшемся множестве{A → C, A → B, C → D, D → C}.
{A}⁺ = {A} ∪ {C} (из A→C) ∪ {B} (из A→B) ∪ {D} (из C→D) = {A, B, C, D}.
АтрибутDвыводится через транзитивную цепочкуA → CиC → D! Следовательно, зависимостьA → Dизбыточна и удаляется. - Проверяем остальные зависимости (
A → C,A → B,C → D,D → C) — ни одна из них не выводится из оставшихся.
F_min = { A → B, A → C, C → D, D → C }
7. Вопросы и задания для самопроверки
ФЗ X → Y тривиальна, если зависимая часть уже является подмножеством детерминанта (Y ⊆ X). Она не несет новой информации (например, {ID, Имя} → {Имя}). Нетривиальная зависимость содержит хотя бы один новый атрибут справа.
Потому что если X → Y, то расширение обеих частей XZ → YZ гарантирует однозначность. Если бы мы добавили атрибуты только справа (X → YZ), это означало бы ложное утверждение, будто исходный набор X определяет посторонний атрибут Z.
Суперключ — это любой набор атрибутов, однозначно идентифицирующий кортеж (K⁺ = U). Потенциальный ключ — это минимальный суперключ, то есть суперключ, не содержащий избыточных атрибутов.
Декомпозиция X → YZ ⟹ X → Y, X → Z переводит все зависимости к атомарным правым частям, что позволяет независимо проверять на избыточность каждую отдельную связь.
Возникает избыточность данных и аномалия обновления: свойства сущности, зависящей лишь от части ключа, будут многократно дублироваться для каждой комбинации составного ключа.