Зачем используют нормализацию баз данных?

Ответ

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

Решаемые проблемы (аномалии):

  • Аномалия обновления: При изменении данных (например, адреса клиента) нужно обновлять множество строк в разных местах, что ведёт к ошибкам и неконсистентности.
  • Аномалия добавления: Невозможно добавить данные об одном объекте (новый город), не добавив связанный с ним другой объект (клиента из этого города).
  • Аномалия удаления: Удаление одной записи (последний заказ клиента) может привести к потере другой информации (данные о самом клиенте).

Практическая польза:

  1. Устранение дублирования: Данные хранятся в одном месте. Например, информация о пользователе — в таблице users, а не копируется в каждую таблицу заказов или сообщений.
  2. Сохранение целостности: Изменения вносятся один раз. Связи обеспечиваются внешними ключами.
  3. Упрощение запросов и модификаций: Структура становится более логичной и предсказуемой.
  4. Экономия дискового пространства (хотя это не главная цель в современном мире).

Пример из практики: До нормализации (плохо):

CREATE TABLE orders (
    order_id INT,
    customer_name VARCHAR(100), -- Дублируется для каждого заказа
    customer_phone VARCHAR(20), -- Дублируется для каждого заказа
    product_name VARCHAR(100),
    order_date DATE
);

После нормализации (хорошо):

CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(100),
    phone VARCHAR(20)
);

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id), -- Ссылка по внешнему ключу
    product_name VARCHAR(100),
    order_date DATE
);

В работе я обычно стремлюсь к 3NF (третьей нормальной форме), которая устраняет транзитивные зависимости.

Ответ 18+ 🔞

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

Если не нормализовать, получаются три главные засады, или, как умники говорят, аномалии:

  1. Аномалия обновления: Допустим, клиентка Маша сменила номер телефона. А у тебя её номер тупо скопирован в 50 разных записей заказов. И вот ты сидишь, как дурак, и меняешь его вручную в полусотне мест. Забыл в одном месте — всё, данные ебнулись, теперь где-то старый номер висит. Доверия ебать ноль к такой информации.
  2. Аномалия добавления: Хочешь просто добавить в базу новый город «Мухосранск», чтобы он в справочнике был. Не выйдет! Потому что у тебя город приколочен гвоздями к таблице клиентов. Чтобы город добавить, тебе надо придумать какого-то левого клиента из этого города. Ёперный театр!
  3. Аномалия удаления: Клиент Иван сделал один заказ и пропал. Ты удаляешь этот последний заказ — и бац! — вместе с заказом нахуй стирается и сам Иван со всеми его реквизитами. Информация потеряна. Накрылся медным тазом весь учёт.

А теперь практическая польза, ради которой всё это стоит делать:

  1. Нет дублированию. Инфа о клиенте живёт в одном-единственном святом месте — в таблице users. Не копируется, как сумасшедшая, в заказы, сообщения и отзывы. Экономия места — приятный бонус, но главное — порядок.
  2. Целостность на высоте. Поменял телефон в одном месте — он автоматом везде актуален. Связи между таблицами держат внешние ключи, они не дают удалить клиента, пока у него есть заказы. Волнение ебать отступает.
  3. Запросы писать — одно удовольствие. Всё логично разложено. Хочешь данные клиента с его заказами — простой JOIN сделаешь и спишь спокойно.

Пример из жизни, чтобы вообще всё встало на свои места:

Было — пиздец и бардак (как тот гараж):

CREATE TABLE orders (
    order_id INT,
    customer_name VARCHAR(100), -- Один и тот же Вася Пупкин будет повторяться 100 раз
    customer_phone VARCHAR(20), -- И его телефон тоже
    product_name VARCHAR(100),
    order_date DATE
);

Представь, у Васи сменился телефон. Удивление пиздец, сколько строк придётся лазать и править.

Стало — красота и грация (процеженная тумбочка с ящиками):

CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(100),
    phone VARCHAR(20)
);

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id), -- Ссылка по внешнему ключу
    product_name VARCHAR(100),
    order_date DATE
);

Теперь данные о Василии — в одном экземпляре в customers. А в заказах только его ID. Телефон поменял в одном месте — и да похуй, сколько у него заказов, везде будет актуально. Удалишь все заказы — Вася останется в базе жить и здравствовать.

В работе я обычно гонюсь за 3NF (третьей нормальной формой). Если просто, она добивает последний бардак — убирает эти ебушки-воробушки, когда данные зависят не напрямую от ключа, а через другие поля. В общем, делает так, чтобы каждая сущность отвечала только за свою манду с ушами и больше ни за чью.