← Назад к вопросам

Что такое нормализация и нормальные формы?

2.3 Middle🔥 141 комментариев
#SQL и базы данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Нормализация БД и нормальные формы

Нормализация — это процесс организации таблиц в реляционной БД с целью уменьшения избыточности данных, улучшения целостности и предотвращения аномалий при вставке, обновлении и удалении данных. Нормальные формы (NF) — это набор правил, которым должна соответствовать БД.

Задачи нормализации

  • Устранение дублирования данных
  • Предотвращение аномалий (insert, update, delete)
  • Улучшение целостности данных
  • Упрощение запросов и обновлений
  • Оптимизация производительности

Первая нормальная форма (1NF)

Требование: Каждый атрибут содержит только атомарные (неделимые) значения. Нет повторяющихся групп.

Не соответствует 1NF:

CREATE TABLE Books_Bad (
    id INT,
    title VARCHAR(100),
    authors VARCHAR(500)  -- Несколько авторов в одном поле
);

Соответствует 1NF:

CREATE TABLE Authors (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE Books (
    id INT PRIMARY KEY,
    title VARCHAR(100)
);

CREATE TABLE BookAuthors (
    book_id INT,
    author_id INT,
    PRIMARY KEY (book_id, author_id),
    FOREIGN KEY (book_id) REFERENCES Books(id),
    FOREIGN KEY (author_id) REFERENCES Authors(id)
);

Вторая нормальная форма (2NF)

Требование: БД должна быть в 1NF И каждый неключевой атрибут должен функционально зависеть от всего первичного ключа, а не от его части.

Не соответствует 2NF (составной ключ):

CREATE TABLE StudentCourses_Bad (
    student_id INT,
    course_id INT,
    student_name VARCHAR(100),  -- Зависит только от student_id, не от всего ключа
    PRIMARY KEY (student_id, course_id)
);

Соответствует 2NF:

CREATE TABLE Students (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE Courses (
    id INT PRIMARY KEY,
    title VARCHAR(100)
);

CREATE TABLE StudentCourses (
    student_id INT,
    course_id INT,
    PRIMARY KEY (student_id, course_id),
    FOREIGN KEY (student_id) REFERENCES Students(id),
    FOREIGN KEY (course_id) REFERENCES Courses(id)
);

Третья нормальная форма (3NF)

Требование: БД должна быть в 2NF И каждый неключевой атрибут не должен зависеть от других неключевых атрибутов (нет транзитивной зависимости).

Не соответствует 3NF:

CREATE TABLE Employees_Bad (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    department_id INT,
    department_name VARCHAR(100)  -- Зависит от department_id, не от id
);

Соответствует 3NF:

CREATE TABLE Departments (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE Employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    department_id INT,
    FOREIGN KEY (department_id) REFERENCES Departments(id)
);

Боюс-Кодд нормальная форма (BCNF)

Требование: Каждый детерминант должен быть потенциальным ключом. Более строгая чем 3NF.

-- Пример: студент может иметь одного тьютора на предмет
CREATE TABLE StudentTutors (
    student_id INT,
    subject_id INT,
    tutor_id INT,
    PRIMARY KEY (student_id, subject_id, tutor_id),
    UNIQUE (subject_id, tutor_id)  -- BCNF ограничение
);

Практический пример: E-commerce система

-- Customers (соответствует всем нормальным формам)
CREATE TABLE Customers (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100)
);

-- Products
CREATE TABLE Products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    category_id INT,
    FOREIGN KEY (category_id) REFERENCES Categories(id)
);

-- Categories
CREATE TABLE Categories (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

-- Orders
CREATE TABLE Orders (
    id INT PRIMARY KEY,
    customer_id INT,
    order_date TIMESTAMP,
    FOREIGN KEY (customer_id) REFERENCES Customers(id)
);

-- OrderItems (соединительная таблица)
CREATE TABLE OrderItems (
    id INT PRIMARY KEY,
    order_id INT,
    product_id INT,
    quantity INT,
    price DECIMAL(10, 2),
    FOREIGN KEY (order_id) REFERENCES Orders(id),
    FOREIGN KEY (product_id) REFERENCES Products(id)
);

Денормализация

Иногда для улучшения производительности используется денормализация — добавление избыточных данных или дублирование информации:

-- Денормализованное добавление для быстроты
ALTER TABLE Orders ADD COLUMN total_amount DECIMAL(10, 2);
-- Это дублирует информацию (можно вычислить из OrderItems),
-- но ускоряет запросы

Вывод: Нормализация — это ключевой процесс проектирования БД, который обеспечивает целостность, предотвращает ошибки и упрощает управление данными. В Data Engineering нужно балансировать между нормализацией (для точности) и денормализацией (для производительности).