Ответ
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).