Что такое вторая нормальная форма (2NF) в реляционных базах данных?

Ответ

Вторая нормальная форма (2NF) — это правило проектирования реляционных баз данных, которое устраняет частичные зависимости неключевых атрибутов от составного первичного ключа.

Условия для приведения таблицы к 2NF:

  1. Таблица уже находится в первой нормальной форме (1NF) (все значения атомарны, нет повторяющихся групп).
  2. Каждый неключевой атрибут должен полностью зависеть от ВСЕГО первичного ключа, а не от его части.

Пример нарушения 2NF:

-- Заказ с несколькими товарами. Составной PK: (order_id, product_id)
CREATE TABLE OrderDetails (
    order_id INT,
    product_id INT,
    product_name VARCHAR(100), -- НЕКЛЮЧЕВОЙ атрибут
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);

Проблема: Атрибут product_name зависит только от части ключа — product_id, а не от всей пары (order_id, product_id). Это приводит к аномалиям:

  • Избыточность: Название товара дублируется в каждой строке заказа.
  • Аномалия обновления: Чтобы изменить название товара, нужно обновить все строки, где он встречается.
  • Аномалия удаления: Если удалить последний заказ с товаром, информация о его названии будет потеряна.

Приведение к 2NF (декомпозиция):

-- Таблица для связи Заказ-Товар (хранит только ключи и количество)
CREATE TABLE OrderItems (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id),
    FOREIGN KEY (order_id) REFERENCES Orders(id),
    FOREIGN KEY (product_id) REFERENCES Products(id)
);

-- Отдельная таблица для данных о товаре
CREATE TABLE Products (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100)
    -- другие атрибуты товара
);

Теперь product_name полностью зависит от своего собственного первичного ключа product_id. Аномалии устранены.

Ответ 18+ 🔞

Да ты посмотри, какая история интересная вырисовывается! Вторая нормальная форма, блядь. Это ж не просто так, какая-то хуйня, а целая философия, чтобы таблицы в базе не превращались в сраное месиво.

Представь себе, сидит такой админ, пьёт кофе, и тут бац — аномалия обновления, ёпта! Всё потому, что кто-то поленился и запихнул product_name не в ту таблицу. Получается, название товара привязано только к его айдишнику, а ключ-то составной, из двух полей! Это ж чистой воды частичная зависимость, блядь. Как будто ты надел один ботинок и пошёл по лужам — одной ногой сухо, а второй полная жопа.

Вот смотри на этот ужасный пример. Ну кто так делает-то, а?

CREATE TABLE OrderDetails (
    order_id INT,
    product_id INT,
    product_name VARCHAR(100), -- Вот эта хитрая жопа!
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);

Сидит эта product_name и думает: «Мне на order_id похуй, я и так от product_id завишу». И начинается: дублирование данных овердохуища, чтобы поменять название — надо полбазы переписать, а удалишь заказ — и товар как будто и не существовал вовсе! Пиздец, а не проектирование.

А чтобы не было этого цирка, надо просто развести эти сущности по разным углам ринга. Как два буйных мужика в подъезде — лучше их в разные квартиры.

-- Эта таблица теперь только про связи. Чисто, аккуратно.
CREATE TABLE OrderItems (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id),
    FOREIGN KEY (order_id) REFERENCES Orders(id),
    FOREIGN KEY (product_id) REFERENCES Products(id)
);

-- А сюда уже все данные о товаре. Пусть тут живут.
CREATE TABLE Products (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100)
);

Вот теперь красота! Каждый атрибут полностью зависит от ВСЕГО своего ключа, ни одной частичной зацепки. Аномалии — в рот меня чих-пых, рассосались. База дышит ровно, админ пьёт кофе спокойно. Всё гениальное просто, блядь. Главное — не накосячить на самом старте.