Третья нормальная форма (3NF) — это шаг на пути к еще большему порядку в наших данных. Вкратце, таблица находится в 3NF, если:
- Она уже находится во второй нормальной форме (2NF).
- Все неключевые атрибуты зависят только от первичного ключа и ни от чего другого (никаких транзитивных зависимостей!).
Другими словами, 3NF требует, чтобы все данные в таблице были напрямую связаны с её первичным ключом и не зависели от других неключевых атрибутов.
Транзитивная зависимость возникает, если атрибут А зависит от атрибута В, а атрибут В зависит от атрибута С, что создаёт цепочку зависимостей А → В → С. Например, «Сотрудник» зависит от «Отдела», а «Отдел» зависит от «Расположения». Получается, что «Сотрудник» транзитивно зависит от «Расположения».
Пример нарушения 3NF
Предположим, у нас есть таблица employees, которая хранит данные о сотрудниках:
| employee_id | name | department | department_manager |
|---|---|---|---|
| 1 | Otto Lin | Marketing | Leo Zhang |
| 2 | Alex Song | Finance | Maria Chi |
| 3 | Anna Ming | Finance | Maria Chi |
Здесь:
employee_id— первичный ключ.departmentиdepartment_manager— неключевые атрибуты.
На первый взгляд всё кажется нормальным, но если мы приглядимся, то заметим проблему: department_manager зависит не от employee_id, а от department. Таким образом, возникает транзитивная зависимость: employee_id → department → department_manager.
Проблемы, которые могут возникнуть
Если мы изменим имя директора департамента («Финансы»), нам придётся обновлять все строки, где указан этот департамент. Если мы случайно забудем обновить одну из строк, данные станут несогласованными. Это головная боль, которой можно избежать.
Приведение таблицы к 3NF
Чтобы устранить транзитивные зависимости, мы разделим таблицу на две: одна будет хранить данные о сотрудниках, а другая — о департаментах.
Таблица employees
| employee_id | name | department |
|---|---|---|
| 1 | Otto Lin | Маркетинг |
| 2 | Alex Song | Финансы |
| 3 | Anna Ming | Финансы |
Таблица departments
| department | department_manager |
|---|---|
| Маркетинг | Leo Zhang |
| Финансы | Maria Chi |
Теперь всё структурировано, и каждая таблица занимается своим делом:
- Таблица
employeesхранит данные о сотрудниках. - Таблица
departmentsхранит данные о департаментах и их менеджерах.
Если менеджер департамента изменится, нам нужно будет обновить только одну строку в таблице departments, а не во всех записях сотрудников.
Как определить, что таблица нарушает 3NF?
Чтобы понять, что таблица нарушает 3NF, проверьте:
- Есть ли в таблице транзитивные зависимости? Например, атрибут A зависит от атрибута B, который зависит от атрибута C.
- Все ли неключевые атрибуты напрямую зависят от первичного ключа? Если что-то зависит от другого неключевого атрибута, то таблица не находится в 3NF.
Практический пример: магазин
Рассмотрим таблицу sales, которая содержит данные о продажах:
| sale_id | product_name | product_price | customer_name |
|---|---|---|---|
| 1 | Телефон | 20 000 | Otto Lin |
| 2 | Ноутбук | 50 000 | Alex Song |
| 3 | Телефон | 20 000 | Anna Ming |
Здесь мы явно видим избыточность: информация о цене товара повторяется для каждой продажи. Если цена изменится, данные сразу теряют согласованность.
Чтобы устранить нарушение 3NF, мы разделим таблицу на две:
- Таблица
salesбудет хранить сведения о продажах. - Таблица
products— данные о товарах и их ценах.
Таблица sales
| sale_id | product_id | customer_name |
|---|---|---|
| 1 | 1 | Otto Lin |
| 2 | 2 | Alex Song |
| 3 | 1 | Anna Ming |
Таблица products
| product_id | product_name | product_price |
|---|---|---|
| 1 | Телефон | 20 000 |
| 2 | Ноутбук | 50 000 |
Теперь, если цена товара изменится, мы просто обновляем одну строку в таблице products, и данные остаются согласованными.
Практическое задание
Вот вам задачка: у вас есть таблица students_courses следующего вида:
| student_id | student_name | course_name | teacher_name |
|---|---|---|---|
| 1 | Otto Lin | Математика | Maria Chi |
| 2 | Alex Song | Программирование | Leo Zhang |
| 1 | Otto Lin | Программирование | Leo Zhang |
Разделите таблицу так, чтобы она соответствовала 3NF. Подсказка: вам нужно создать три таблицы (students, courses, teachers) и правильно связать их.
Почему важно соблюдать 3NF?
Почему вообще стоит заморачиваться с третьей нормальной формой (3NF)? Потому что она реально упрощает жизнь. Когда таблицы приведены к 3NF, данные становятся аккуратнее — никакой лишней дублировки, а значит, меньше шансов что-то случайно поломать. Обновления проходят быстрее и проще, ведь всё хранится в одном месте, а не копипастится по всем строкам.
К тому же структура базы становится гибче. Хочешь добавить новое поле или изменить старое — не нужно перекраивать всю систему.
Но, как и в любой хорошей истории, есть нюанс: слишком рьяная нормализация может вылиться в кучу мелких таблиц и сложные запросы с множеством JOIN’ов. Иногда это действительно может тормозить. Так что главное — чувство меры. Там, где нужно — нормализуйте, а где проще оставить чуть-чуть избыточности — не бойтесь.
Дальше будем разбираться глубже: научимся правильно выстраивать связи между таблицами и создавать базы, которые и удобны, и надёжны. Вперёд, к отличному дизайну базы данных!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ