Расскажи о третьей нормальной форме базы данных
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Третья нормальная форма (3NF) базы данных
Третья нормальная форма (3NF) — это уровень нормализации схемы БД, который обеспечивает минимальную избыточность данных при сохранении возможности эффективного выполнения запросов. 3NF считается стандартом для большинства операционных баз данных.
Условия для 3NF
Таблица находится в 3NF, если она:
- Находится в 2NF — все неключевые атрибуты полностью зависят от первичного ключа (не только частью)
- Не содержит транзитивных зависимостей — неключевые атрибуты не зависят друг от друга, только от первичного ключа
Главное правило 3NF: "Неключевой атрибут должен зависеть только от первичного ключа, ничего кроме первичного ключа и ничего, кроме первичного ключа"
Пример нарушения 3NF
Таблица без 3NF (имеет транзитивную зависимость):
Таблица Students:
┌──────────┬──────────┬────────────┬──────────────┐
│ student_id │ name │ city_id │ city_name │
├──────────┼──────────┼────────────┼──────────────┤
│ 1 │ Иван │ 10 │ Москва │
│ 2 │ Петр │ 10 │ Москва │
│ 3 │ Мария │ 20 │ Санкт-Петербург │
└──────────┴──────────┴────────────┴──────────────┘
Проблема: city_name зависит от city_id, а не напрямую от student_id. Это транзитивная зависимость.
- Если изменить название города, придётся обновлять несколько строк
- Если удалить все студентов из города, потеряем информацию о самом городе
- Дублирование данных (город повторяется много раз)
Преобразование в 3NF
Разделяем на две таблицы:
// Таблица 1: Students (содержит только прямые зависимости от PK)
Таблица Students:
┌──────────┬──────────┬────────────┐
│ student_id │ name │ city_id │
├──────────┼──────────┼────────────┤
│ 1 │ Иван │ 10 │
│ 2 │ Петр │ 10 │
│ 3 │ Мария │ 20 │
└──────────┴──────────┴────────────┘
// Таблица 2: Cities (город и его свойства)
Таблица Cities:
┌──────────┬────────────────────┐
│ city_id │ city_name │
├──────────┼────────────────────┤
│ 10 │ Москва │
│ 20 │ Санкт-Петербург │
└──────────┴────────────────────┘
Теперь каждая таблица в 3NF: каждый неключевой атрибут зависит только от первичного ключа.
Пример с покупками
Нарушение 3NF:
Таблица Orders (содержит транзитивные зависимости):
┌──────────┬────────────┬──────────┬─────────────────┬──────────────┐
│ order_id │ customer_id │ product_id │ product_name │ category │
├──────────┼────────────┼──────────┼─────────────────┼──────────────┤
│ 101 │ 1 │ 200 │ Ноутбук │ Электроника │
│ 102 │ 2 │ 200 │ Ноутбук │ Электроника │
│ 103 │ 1 │ 300 │ Монитор │ Электроника │
└──────────┴────────────┴──────────┴─────────────────┴──────────────┘
Проблемы:
product_nameиcategoryзависят отproduct_id, а не отorder_id- Дублирование названий товаров и категорий
Коррекция в 3NF:
// Таблица Orders (только direct dependencies)
Таблица Orders:
┌──────────┬────────────┬──────────┐
│ order_id │ customer_id │ product_id │
├──────────┼────────────┼──────────┤
│ 101 │ 1 │ 200 │
│ 102 │ 2 │ 200 │
│ 103 │ 1 │ 300 │
└──────────┴────────────┴──────────┘
// Таблица Products (продукт и его свойства)
Таблица Products:
┌──────────┬──────────────┬──────────────┐
│ product_id │ product_name │ category │
├──────────┼──────────────┼──────────────┤
│ 200 │ Ноутбук │ Электроника │
│ 300 │ Монитор │ Электроника │
└──────────┴──────────────┴──────────────┘
Сравнение нормальных форм
1NF — Исходная форма
↓ Устраняем частичные зависимости
2NF — Вторая нормальная форма
↓ Устраняем транзитивные зависимости
3NF — Третья нормальная форма ✓
↓ (редко используется)
BCNF — Нормальная форма Бойса-Кодда
Практический пример на Java/Hibernate
// Класс без 3NF (содержит лишнюю информацию)
@Entity
public class Order {
@Id
private Long orderId;
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
@ManyToOne
@JoinColumn(name = "product_id")
private Product product;
// Лишнее! product_name и category уже в Product
private String productName; // Транзитивная зависимость
private String productCategory; // Транзитивная зависимость
}
// Правильная реализация в 3NF
@Entity
public class Order {
@Id
private Long orderId;
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
@ManyToOne
@JoinColumn(name = "product_id")
private Product product;
// Никаких дублей информации о product
}
@Entity
public class Product {
@Id
private Long productId;
private String productName;
private String category;
}
Преимущества 3NF
- Минимальная избыточность — каждый атрибут хранится один раз
- Целостность данных — нет аномалий обновления и удаления
- Эффективность операций — правильно спроектирована для большинства операций
- Гибкость — легче добавлять новые свойства сущностей
Недостатки 3NF
- Больше JOIN'ов — при получении связанных данных нужны соединения таблиц
- Сложнее запросы — требуются более сложные SELECT'ы
- Производительность — для OLAP систем может быть медленнее
Для систем, требующих высокой производительности чтения, используют денормализацию и хранилища данных (Data Warehouse), но для операционных OLTP систем 3NF остаётся золотым стандартом.