Sobes.tech
Назад к вопросам
Junior — Middle
54

Какими методами можно привести структуру базы данных к нормализованному виду?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Нормализация базы данных — это разбиение данных на связанные таблицы так, чтобы уменьшить дублирование и избежать аномалий вставки, обновления и удаления. Обычно для этого приводят схему к 1NF, 2NF, 3NF и при необходимости дальше. На практике это означает правильное выделение сущностей, ключей и связей между ними.

Определение:

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

Чаще всего используют такие шаги:

  • Первая нормальная форма (1NF) — все поля атомарны, в ячейке хранится одно значение, а не список или массив значений.
  • Вторая нормальная форма (2NF) — все неключевые поля зависят от всего составного ключа, а не от его части.
  • Третья нормальная форма (3NF) — неключевые поля зависят только от ключа, а не друг от друга.
  • Иногда дополнительно применяют BCNF и дальше, если в схеме остаются более тонкие аномалии.

Пример использования:

Допустим, есть таблица заказов, где в одной строке хранятся и данные клиента, и данные заказа:

orders
- order_id
- order_date
- customer_name
- customer_phone
- product_name
- product_price

Такая структура плохо масштабируется: имя и телефон клиента повторяются в каждой покупке. Нормализация здесь будет такой:

CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    customer_name TEXT NOT NULL,
    customer_phone TEXT NOT NULL
);

CREATE TABLE products (
    product_id SERIAL PRIMARY KEY,
    product_name TEXT NOT NULL,
    product_price NUMERIC(10, 2) NOT NULL
);

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    order_date DATE NOT NULL,
    customer_id INT NOT NULL REFERENCES customers(customer_id)
);

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

Теперь данные о клиенте и товаре хранятся отдельно, а в заказе остаются только ссылки на них.

Пояснение кода:

В этом примере код показывает разбиение одной денормализованной таблицы на несколько связанных сущностей.

  1. customers хранит только данные клиента.
  2. products хранит только данные товара.
  3. orders связывает заказ с клиентом через customer_id.
  4. order_items хранит состав заказа и связывает заказ с товарами.

Такое разбиение убирает дублирование: если телефон клиента изменится, его нужно обновить только в одной строке таблицы customers, а не во всех заказах. Аналогично, цена товара хранится отдельно от заказов, если по бизнес-логике она должна быть актуальной справочной ценой.

Ключевые моменты:

  • Нормализация нужна, чтобы уменьшить дублирование данных и избежать аномалий обновления.
  • Основной инструмент — разбиение таблиц по сущностям и зависимостям.
  • Проверяют соблюдение 1NF, 2NF и 3NF, а при необходимости используют более строгие формы.
  • Важно правильно выбрать первичные и внешние ключи.
  • Слишком сильная нормализация может усложнить запросы, поэтому в реальных системах иногда часть данных денормализуют ради производительности.