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

Ответ

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

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

Проще: В таблице не должно быть ситуации, когда A → B → C, где A — первичный ключ, а B и C — неключевые атрибуты.

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

order_id (PK) customer_id customer_name product quantity
1001 CUST77 Иванов Иван Монитор 1
1002 CUST77 Иванов Иван Клавиатура 2

Проблема: Атрибут customer_name зависит не напрямую от первичного ключа order_id, а от другого неключевого атрибута customer_id (транзитивная зависимость: order_id → customer_id → customer_name). Это приводит к аномалиям:

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

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

-- Таблица заказов (Order)
CREATE TABLE Orders (
    order_id INT PRIMARY KEY,
    customer_id INT, -- Внешний ключ
    product VARCHAR(100),
    quantity INT
);

-- Таблица клиентов (Customer)
CREATE TABLE Customers (
    customer_id INT PRIMARY KEY,
    customer_name VARCHAR(100)
);

-- Добавляем связь
ALTER TABLE Orders ADD FOREIGN KEY (customer_id) REFERENCES Customers(customer_id);

Теперь customer_name зависит только от первичного ключа Customers.customer_id, а в таблице Orders остались только атрибуты, напрямую зависящие от её первичного ключа. Аномалии устранены.

Ответ 18+ 🔞

А, ну это про третью нормальную форму, блядь! Слушай, сейчас я тебе так объясню, что ты, сука, сам от себя офигеешь. Это ж проще пареной репы, если не загоняться в дебри, как эти, блядь, теоретики.

Представь себе, ты ведёшь учёт заказов, как самый обычный распиздяй. Записал в одну кучу: номер заказа, айдишник клиента, его имя, товар и количество. Вроде логично, да? Ну вот смотри, что получается:

order_id (PK) customer_id customer_name product quantity
1001 CUST77 Иванов Иван Монитор 1
1002 CUST77 Иванов Иван Клавиатура 2

Всё вроде на месте, но тут, сука, засада! Имя-то клиента привязано не к номеру заказа, а к его айдишнику! Получается цепочка, блядь: order_id → customer_id → customer_name. Это и есть та самая транзитивная зависимость, от которой 3NF хочет нас избавить, как от дурной привычки.

И что в итоге? А в итоге пиздец, Карл! Представь, этот Иванов Иван возьми и женись, стань Ивановым Петром, блядь. И чтобы сменить имя, тебе придётся лазить по всем его заказам и везде править. А если заказов овердохуища? Да ты с ума сойдёшь! Или удалишь его последний заказ — и всё, имя клиента нахуй пропало из базы, как будто его и не было. Во какие распиздяйства творятся!

Так вот, третья нормальная форма говорит: «Хуй вам, а не зависимости!» Надо раскидать это всё по разным углам.

-- Вот тебе таблица под заказы, пусть тут только про заказы и будет
CREATE TABLE Orders (
    order_id INT PRIMARY KEY,
    customer_id INT, -- Ссылочка на клиента, и всё
    product VARCHAR(100),
    quantity INT
);

-- А вот отдельная хата для клиентов, где они царь и бог
CREATE TABLE Customers (
    customer_id INT PRIMARY KEY,
    customer_name VARCHAR(100)
);

-- И связываем их, как сиамских близнецов, но чтоб не мешали друг другу
ALTER TABLE Orders ADD FOREIGN KEY (customer_id) REFERENCES Customers(customer_id);

Вот теперь красота! В таблице заказов осталось только то, что напрямую от заказа зависит: что купили и сколько. А имя клиента сидит в своей отдельной табличке и зависит только от своего собственного айдишника. Нету больше дублирования, не надо бегать и всё обновлять. Изменил имя в одном месте — и по всей базе автоматом везде правильно. Во, ёпта, вот это я понимаю — порядок! Не то что раньше, в пизду.