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

Для чего нужно понятие нормализации БД?

1.8 Middle🔥 181 комментариев
#Базы данных и SQL

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

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

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

Нормализация БД: назначение и значение

Нормализация базы данных — это процесс структурирования данных для устранения избыточности и зависимостей, обеспечивающий целостность и эффективность хранилища. Это фундаментальная концепция в проектировании реляционных баз данных, которая влияет на качество, производительность и надёжность системы.

Основные цели нормализации

1. Устранение избыточности (anomalies) Без нормализации данные дублируются в разных местах, что приводит к аномалиям:

-- ❌ Денормализованная таблица (много redundancy)
CREATE TABLE OrderDetails (
    order_id INT,
    customer_name VARCHAR(255),
    customer_email VARCHAR(255),
    customer_phone VARCHAR(20),
    product_name VARCHAR(255),
    category_name VARCHAR(100),
    price DECIMAL(10,2)
);
-- Если изменить email клиента, нужно обновить все его заказы!

2. Обеспечение целостности данных (data integrity) Нормализация через Foreign Key и отдельные таблицы гарантирует, что удаление или изменение данных не создаст противоречия:

-- ✅ Нормализованная схема (3NF)
CREATE TABLE Customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(255),
    email VARCHAR(255),
    phone VARCHAR(20)
);

CREATE TABLE Products (
    product_id INT PRIMARY KEY,
    name VARCHAR(255),
    category_id INT,
    price DECIMAL(10,2),
    FOREIGN KEY (category_id) REFERENCES Categories(category_id)
);

CREATE TABLE Orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    FOREIGN KEY (customer_id) REFERENCES Customers(customer_id)
);

CREATE TABLE OrderItems (
    order_item_id INT PRIMARY KEY,
    order_id INT,
    product_id INT,
    quantity INT,
    FOREIGN KEY (order_id) REFERENCES Orders(order_id),
    FOREIGN KEY (product_id) REFERENCES Products(product_id)
);

Формы нормализации (Normal Forms)

Процесс идёт от 1NF к 5NF:

1NF (First Normal Form) — устранение повторяющихся групп

-- ❌ Нарушение 1NF (массив phone_numbers в одной ячейке)
CREATE TABLE Users (
    user_id INT,
    name VARCHAR(255),
    phone_numbers VARCHAR(500)
);

-- ✅ Соответствие 1NF
CREATE TABLE Users (
    user_id INT PRIMARY KEY,
    name VARCHAR(255)
);

CREATE TABLE UserPhones (
    phone_id INT PRIMARY KEY,
    user_id INT,
    phone_number VARCHAR(20),
    FOREIGN KEY (user_id) REFERENCES Users(user_id)
);

2NF — устранение частичной зависимости от составного первичного ключа

3NF — устранение транзитивной зависимости между неключевыми атрибутами

Практические преимущества

Меньше обновлений (Update Efficiency)

// В денормализованной схеме пришлось бы обновлять email везде:
preparedStatement = connection.prepareStatement(
    "UPDATE OrderDetails SET customer_email = ? WHERE customer_id = ?"
);

// В нормализованной — только в одном месте:
preparedStatement = connection.prepareStatement(
    "UPDATE Customers SET email = ? WHERE customer_id = ?"
);

Консистентность (Consistency) Одна версия правды для каждого объекта — исключены противоречия в данных.

Экономия дискового пространства Отсутствие дублирования снижает объём БД.

Производительность запросов Хотя нормализация может потребовать JOIN'ов, хорошо спроектированные индексы компенсируют это и часто улучшают общую производительность.

Денормализация: исключения

В некоторых случаях (OLAP системы, аналитика) целесообразна контролируемая денормализация для скорости чтения:

CREATE MATERIALIZED VIEW OrderSummary AS
SELECT 
    c.customer_id,
    c.name,
    COUNT(o.order_id) as total_orders,
    SUM(oi.quantity) as total_items
FROM Customers c
LEFT JOIN Orders o ON c.customer_id = o.customer_id
LEFT JOIN OrderItems oi ON o.order_id = oi.order_id
GROUP BY c.customer_id, c.name;

Вывод

Нормализация — это не просто теория, а практический инструмент, который предотвращает баги, упрощает поддержку кода и обеспечивает надёжность системы.