Ответ
1. Первая нормальная форма (1NF) Таблица находится в 1NF, если:
- Все значения атрибутов атомарны (неделимы). Нет составных значений, массивов или списков в одной ячейке.
- Нет повторяющихся групп столбцов.
- Определён первичный ключ (явно или неявно).
Пример нарушения и исправления:
-- НАРУШЕНИЕ 1NF: неатомарное значение, список в одной ячейке
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer_name VARCHAR(100),
items VARCHAR(500) -- Например: 'Laptop, Mouse, Keyboard'
);
-- СООТВЕТСТВИЕ 1NF: каждая сущность в отдельной строке
CREATE TABLE OrderItems (
order_id INT,
item_name VARCHAR(100),
quantity INT,
PRIMARY KEY (order_id, item_name),
FOREIGN KEY (order_id) REFERENCES Orders(order_id)
);
-- Данные: (1, 'Laptop', 1), (1, 'Mouse', 1), (1, 'Keyboard', 1)
2. Вторая нормальная форма (2NF) Таблица находится в 2NF, если:
- Она уже в 1NF.
- Все неключевые атрибуты полностью функционально зависят от всего составного первичного ключа (нет частичных зависимостей).
Пример нарушения и исправления:
-- НАРУШЕНИЕ 2NF: цена зависит только от product_id, а не от пары (order_id, product_id)
CREATE TABLE OrderDetails (
order_id INT,
product_id INT,
product_name VARCHAR(100), -- Частичная зависимость: зависит только от product_id
price DECIMAL(10,2), -- Частичная зависимость: зависит только от product_id
quantity INT,
PRIMARY KEY (order_id, product_id)
);
-- СООТВЕТСТВИЕ 2NF: выносим частичные зависимости в отдельную таблицу
CREATE TABLE Products (
product_id INT PRIMARY KEY,
product_name VARCHAR(100),
price DECIMAL(10,2)
);
CREATE TABLE OrderDetails (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (product_id) REFERENCES Products(product_id)
);
3. Третья нормальная форма (3NF) Таблица находится в 3NF, если:
- Она уже в 2NF.
- Нет транзитивных зависимостей: неключевые атрибуты не зависят от других неключевых атрибутов, а только от первичного ключа.
Пример нарушения и исправления:
-- НАРУШЕНИЕ 3NF: manager зависит от department, а не напрямую от emp_id (транзитивная зависимость)
CREATE TABLE Employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(100),
department VARCHAR(50),
department_manager VARCHAR(100) -- Зависит от department, а не от emp_id
);
-- СООТВЕТСТВИЕ 3NF: выносим транзитивную зависимость
CREATE TABLE Departments (
department_name VARCHAR(50) PRIMARY KEY,
manager VARCHAR(100)
);
CREATE TABLE Employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(100),
department VARCHAR(50),
FOREIGN KEY (department) REFERENCES Departments(department_name)
);
Практический итог: Нормализация уменьшает избыточность данных и аномалии при вставке, обновлении и удалении, но может увеличивать количество JOIN-запросов. Часто идут на компромисс, денормализируя таблицы для производительности на чтение в аналитических системах (OLAP).
Ответ 18+ 🔞
А, нормальные формы, классика жанра! Ну что, разбираем эту матчасть, чтобы не было потом пиздеца в базе данных. Слушай сюда, но не засыпай.
1. Первая нормальная форма (1NF) Это как элементарные правила гигиены, блядь. Таблица в порядке, если:
- В каждой ячейке лежит один простой кусок данных, а не какой-нибудь салат из значений. Никаких списков через запятую — это пиздопроебибна.
- Нет столбцов-близнецов, которые одно и то же означают.
- Есть чёткий главный ключ, который всё идентифицирует. Без этого — пизда рулю.
Смотри, как бывает:
-- КАК НЕ НАДО: запихнул всё в одну кучу, как маньяк
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer_name VARCHAR(100),
items VARCHAR(500) -- Типа 'Ноутбук, Мышь, Клавиатура' — овердохуища говна в одной ячейке
);
-- КАК НАДО: разложил по полочкам, как человек
CREATE TABLE OrderItems (
order_id INT,
item_name VARCHAR(100),
quantity INT,
PRIMARY KEY (order_id, item_name),
FOREIGN KEY (order_id) REFERENCES Orders(order_id)
);
-- Данные теперь нормальные: (1, 'Ноутбук', 1), (1, 'Мышь', 1), (1, 'Клавиатура', 1)
Видишь разницу? В первом случае — хитрая жопа, которая взорвётся при первом же запросе. Во втором — красота.
2. Вторая нормальная форма (2NF) Тут уже посерьёзнее. Чтобы было всё чинно:
- Таблица уже должна быть в 1NF (логично, ёпта).
- Все неключевые поля должны жёстко зависеть от ВСЕГО составного первичного ключа. Если зависят только от части — это хуй с горы, а не зависимость.
Лови пример:
-- НАРУШЕНИЕ: цена и имя товара прилипли только к product_id, а order_id тут как пятое колесо
CREATE TABLE OrderDetails (
order_id INT,
product_id INT,
product_name VARCHAR(100), -- Зависит только от product_id! Подозрение ебать чувствую!
price DECIMAL(10,2), -- И это тоже! Частичная зависимость, мать его!
quantity INT,
PRIMARY KEY (order_id, product_id)
);
-- ИСПРАВЛЕНИЕ: раскидал по своим углам
CREATE TABLE Products (
product_id INT PRIMARY KEY,
product_name VARCHAR(100),
price DECIMAL(10,2)
);
CREATE TABLE OrderDetails (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (product_id) REFERENCES Products(product_id)
);
Вынес информацию о товаре отдельно. Теперь если цена поменяется, её надо править в одном месте, а не впиздюривать во все заказы разом. Удобно, да?
3. Третья нормальная форма (3NF) А это уже высший пилотаж. Условия:
- 2NF пройдена (само собой).
- Никаких транзитивных зависимостей! То есть неключевые поля не должны зависеть от других неключевых полей. Только от ключа, блядь! Иначе получается цепочка, доверия ебать ноль.
Смотри, как ловко нарушают:
-- НАРУШЕНИЕ: менеджер привязан к отделу, а не к сотруднику. Транзитивная зависимость!
CREATE TABLE Employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(100),
department VARCHAR(50),
department_manager VARCHAR(100) -- Вот же ж, мудя! Зависит от department, а не от emp_id!
);
-- ИСПРАВЛЕНИЕ: развёл по разным квартирам
CREATE TABLE Departments (
department_name VARCHAR(50) PRIMARY KEY,
manager VARCHAR(100)
);
CREATE TABLE Employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(100),
department VARCHAR(50),
FOREIGN KEY (department) REFERENCES Departments(department_name)
);
Теперь если начальник отдела сменится, мы меняем одну запись в Departments, а не бегаем и впендюриваем новую фамилию каждому сотруднику. Волнение ебать прошло.
Итог, чувак: Нормализация — это чтобы данные не дублировались и не было аномалий при обновлении. Но за всё надо платить: чем больше таблиц, тем больше JOIN-ов, а это может тормозить. Поэтому для тяжёлых отчётов (OLAP) иногда специально денормализуют — жертвуют аккуратностью ради скорости. Но чтобы нарушать правила, их надо сначала знать, верно? Иначе будет тебе хиросима и нигерсраки в продакшене.