В каких случаях применяется денормализация реляционной базы данных?

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

Ответ

Денормализация — это сознательное дублирование данных или объединение таблиц для оптимизации производительности чтения в ущерб нормализованной форме. Она применяется, когда:

  1. Критична производительность чтения: Частые и сложные JOIN-запросы становятся "узким местом". Объединение таблиц ускоряет выборку.
  2. Создание аналитических отчетов или OLAP-кубов: Предрасчет агрегатов (суммы, средние) и их хранение исключает дорогостоящие вычисления "на лету".
  3. Упрощение запросов: Схема становится понятнее для конечных пользователей или reporting-инструментов.
  4. Географическое распределение данных: Дублирование связанных данных в одну таблицу может упростить шардинг или репликацию.

Пример: Нормализованная vs Денормализованная схема

-- Нормализованная схема (3NF)
CREATE TABLE users (
    user_id INT PRIMARY KEY,
    user_name VARCHAR(100)
);
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL,
    FOREIGN KEY (user_id) REFERENCES users(user_id)
);
-- Запрос требует JOIN
SELECT o.order_id, u.user_name, o.amount
FROM orders o
JOIN users u ON o.user_id = u.user_id;

-- Денормализованная схема (добавлено user_name)
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_id INT,
    user_name VARCHAR(100), -- Дублируем данные из users
    amount DECIMAL
);
-- Запрос выполняется быстрее, без JOIN
SELECT order_id, user_name, amount FROM orders;

Важные компромиссы:

  • Плюсы: Ускорение операций чтения (SELECT).
  • Минусы: Усложнение операций обновления (UPDATE, DELETE) — данные нужно менять в нескольких местах, риск несогласованности. Увеличивается объем хранилища.

Best Practice: Денормализуйте осознанно, документируйте такие решения и рассмотрите альтернативы (индексы, материализованные представления, кэширование) перед изменением схемы.