Условие
Что такое транзитивная зависимость в контексте нормализации базы данных? В какой нормальной форме она устраняется?
Решение
Определение
Транзитивная зависимость — это ситуация, когда неключевой атрибут A зависит от неключевого атрибута B, который, в свою очередь, зависит от первичного ключа PK.
PK → B → A
То есть A зависит от ключа через посредника B, а не напрямую.
Пример
Таблица orders:
| order_id (PK) | client_id | client_name | client_city |
|---|---|---|---|
| 1 | 5 | Иван | Москва |
| 2 | 5 | Иван | Москва |
| 3 | 7 | Маша | Казань |
Здесь:
order_id → client_id(по ключу)client_id → client_name, client_city(атрибуты клиента)- значит
order_id → client_nameтранзитивно черезclient_id
Почему это плохо
- Дублирование —
client_nameповторяется в каждом заказе клиента. - Аномалия обновления — клиент сменил имя → нужно обновить во всех заказах.
- Аномалия удаления — удалив последний заказ клиента, потеряем информацию о клиенте.
Решение — 3NF
Выносим зависимый «островок» в отдельную таблицу:
CREATE TABLE clients (
client_id INT PRIMARY KEY,
client_name TEXT,
client_city TEXT
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
client_id INT REFERENCES clients(client_id),
...
);Теперь order_id → client_id, и никакой транзитивности — атрибуты клиента живут в clients.
Связь с другими формами
- 2NF убирает частичные зависимости от составного PK.
- 3NF убирает транзитивные зависимости от не-ключевых атрибутов.
- BCNF убирает зависимости от ключей-кандидатов (более строгая форма 3NF).
Подводные камни
- Зависимость по PK не транзитивна. Если
client_idсам PK — это просто ссылка по ключу, не нарушение 3NF. - Производные колонки (например,
total = price * qty) — формально нарушают 3NF, но часто хранят ради скорости. - В DWH сознательно нарушают — звезда/снежинка содержит транзитивные зависимости в fact-таблице ради производительности.
Эталонный ответ
Транзитивная зависимость — атрибут зависит от ключа через другой неключевой атрибут (PK → B → A). Устраняется в 3NF путём выноса зависимого «островка» в отдельную таблицу.