Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Уровни нормализации базы данных
Нормализация — процесс организации структуры БД для минимизации дублирования данных и улучшения целостности. Существует 7 уровней нормализации, но в практике используются первые три.
0NF (Ненормализованная форма)
Таблица с повторяющимися группами:
Таблица STUDENTS:
| ID | Name | Phones |
|----|---------|----------------------------------|
| 1 | Иван | 111-11-11, 222-22-22, 333-33-33 |
| 2 | Мария | 444-44-44 |
Проблемы:
- Избыточность — непредсказуемое количество телефонов
- Сложность запросов — нужно парсить строки
- Сложность обновления — добавить телефон сложно
1NF (Первая нормальная форма)
Все значения атомарны (неделимы):
Таблица STUDENTS:
| ID | Name | Phone |
|----|---------|-----------|
| 1 | Иван | 111-11-11 |
| 1 | Иван | 222-22-22 |
| 1 | Иван | 333-33-33 |
| 2 | Мария | 444-44-44 |
Таблица PHONE:
| StudentID | Phone |
|-----------|-----------|
| 1 | 111-11-11 |
| 1 | 222-22-22 |
| 1 | 333-33-33 |
| 2 | 444-44-44 |
Требования 1NF:
- Все ячейки содержат только атомарные значения
- Нет повторяющихся групп
- Каждая ячейка содержит одно значение
2NF (Вторая нормальная форма)
Таблица находится в 1NF и все неключевые атрибуты полностью зависят от первичного ключа:
Таблица COURSE_STUDENTS (без 2NF):
| StudentID | CourseID | StudentName | CourseName | Grade |
|-----------|----------|-------------|---------------|-------|
| 1 | 101 | Иван | Python | 95 |
| 1 | 102 | Иван | JavaScript | 87 |
| 2 | 101 | Мария | Python | 92 |
Проблемы:
- StudentName зависит только от StudentID
- CourseName зависит только от CourseID
- Дублирование данных
Нормализованная структура:
Таблица STUDENTS:
| StudentID | StudentName |
|-----------|-------------|
| 1 | Иван |
| 2 | Мария |
Таблица COURSES:
| CourseID | CourseName |
|----------|---------------|
| 101 | Python |
| 102 | JavaScript |
Таблица ENROLLMENTS:
| StudentID | CourseID | Grade |
|-----------|----------|-------|
| 1 | 101 | 95 |
| 1 | 102 | 87 |
| 2 | 101 | 92 |
Преимущества:
- Удалена частичная зависимость
- Проще обновлять данные — изменяем имя в одном месте
- Меньше дублирования
3NF (Третья нормальная форма)
Таблица находится в 2NF и не содержит транзитивных зависимостей:
Таблица EMPLOYEES (без 3NF):
| EmployeeID | Name | DepartmentID | DepartmentName | DepartmentHead |
|------------|--------|--------------|----------------|----------------|
| 1 | Иван | 10 | IT | Петр |
| 2 | Мария | 10 | IT | Петр |
| 3 | Сергей | 20 | HR | Анна |
Проблемы:
- DepartmentName зависит от EmployeeID через DepartmentID (транзитивная зависимость)
- DepartmentHead зависит через DepartmentID
Нормализованная структура:
Таблица DEPARTMENTS:
| DepartmentID | DepartmentName | DepartmentHead |
|--------------|----------------|----------------|
| 10 | IT | Петр |
| 20 | HR | Анна |
Таблица EMPLOYEES:
| EmployeeID | Name | DepartmentID |
|------------|--------|--------------|
| 1 | Иван | 10 |
| 2 | Мария | 10 |
| 3 | Сергей | 20 |
BCNF (Нормальная форма Бойса-Кодда)
Более строгая версия 3NF. Каждый детерминант является кандидатом на первичный ключ:
Таблица PROFESSORS (без BCNF):
| Professor | Subject | Time |
|-----------|---------|-------|
| Иван | Math | 09:00 |
| Иван | Math | 10:00 | -- Конфликт!
| Петр | Physics | 09:00 |
Проблема: один профессор не может преподавать разные предметы
Решение: создать таблицу PROFESSOR_SUBJECTS
4NF (Четвёртая нормальная форма)
Нет нетривиальных многозначных зависимостей:
Таблица STUDENT_COURSES_BOOKS (без 4NF):
| StudentID | Course | TextBook |
|-----------|--------|----------|
| 1 | Math | Book A |
| 1 | Math | Book B |
| 1 | Python | Book A |
Решение: разделить на STUDENT_COURSES и COURSES_BOOKS
5NF (Пятая нормальная форма)
Таблица должна быть восстановима из проекций (редко используется на практике).
6NF и выше
Рассматривают более сложные случаи зависимостей, редко используются.
Практический пример: E-commerce система
# 1NF нарушение:
# products = [
# {"id": 1, "name": "Laptop", "tags": "electronics, computers"}
# ]
# Правильно (1NF):
# PRODUCTS: id, name
# TAGS: product_id, tag
# 2NF нарушение:
# orders = [
# {"order_id": 1, "customer_id": 1, "customer_name": "Иван"}
# ]
# Правильно (2NF):
# ORDERS: order_id, customer_id
# CUSTOMERS: customer_id, customer_name
# 3NF нарушение:
# orders = [
# {"order_id": 1, "customer_id": 1, "city_id": 1, "city_name": "Moscow"}
# ]
# Правильно (3NF):
# ORDERS: order_id, customer_id, city_id
# CITIES: city_id, city_name
Когда денормализовать?
Иногда намеренно денормализуют для производительности:
-- Нормализованный запрос требует 3 JOIN
SELECT o.id, c.name, SUM(oi.price)
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN order_items oi ON o.id = oi.order_id
GROUP BY o.id;
-- Денормализованная таблица (cache):
CREATE TABLE order_summary AS
SELECT o.id, c.name, SUM(oi.price) as total
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN order_items oi ON o.id = oi.order_id;
Советы при нормализации
- Начни с 1NF — атомарные значения
- Перейди к 2NF — удали частичные зависимости
- Примени 3NF — удали транзитивные зависимости
- Не переусложняй — BCNF часто избыточна
- Мониторь производительность — денормализуй если нужно
- Используй индексы вместо денормализации если возможно
Вывод: нормализация 1NF-3NF — обязательна для большинства приложений. Более высокие уровни редко требуются.