Что такое нормализация базы данных?

«Что такое нормализация базы данных?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нормализация — это процесс проектирования структуры реляционной базы данных, направленный на устранение избыточности данных и аномалий при операциях вставки, обновления и удаления (INSERT, UPDATE, DELETE). Она достигается путем декомпозиции таблиц и приведения их к нормальным формам.

Основные нормальные формы, которые я применяю на практике:

  1. Первая нормальная форма (1NF): Устраняет повторяющиеся группы. Каждое поле содержит атомарные (неделимые) значения, а в таблице нет массивов или списков в одной ячейке.

    • До: Orders(order_id, products: "Книга,Ручка,Блокнот")
    • После: Отдельная таблица Order_Items(order_id, product_name).
  2. Вторая нормальная форма (2NF): Должна выполняться 1NF, и все неключевые атрибуты должны полностью зависеть от всего составного первичного ключа, а не от его части.

    • Проблема: В таблице Order_Items(order_id, product_id, product_name, quantity) поле product_name зависит только от product_id, а не от пары (order_id, product_id).
    • Решение: Вынести product_name в отдельную таблицу Products(product_id, product_name).
  3. Третья нормальная форма (3NF): Должна выполняться 2NF, и не должно быть транзитивных зависимостей (когда неключевой атрибут зависит от другого неключевого атрибута).

    • Проблема: В таблице Orders(order_id, customer_id, customer_phone) поле customer_phone зависит от customer_id, а не напрямую от order_id.
    • Решение: Вынести customer_phone в таблицу Customers(customer_id, customer_phone).

Пример нормализованной схемы для заказов:

-- Основные сущности
CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100) UNIQUE
);

CREATE TABLE products (
    product_id INT PRIMARY KEY,
    name VARCHAR(100),
    price DECIMAL(10,2)
);

-- Связующие таблицы
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id),
    FOREIGN KEY (order_id) REFERENCES orders(order_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id)
);

Преимущества нормализации: целостность данных, эффективное использование памяти, упрощение операций обновления. Недостаток: более сложные запросы с большим количеством JOIN, что иногда требует денормализации для оптимизации чтения в высоконагруженных системах.