Что такое нормализация реляционной базы данных и зачем она нужна?

«Что такое нормализация реляционной базы данных и зачем она нужна?» — вопрос из категории Базы данных, который задают на 25% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нормализация — это процесс проектирования схемы реляционной базы данных, направленный на устранение избыточности данных и аномалий при операциях вставки, обновления и удаления (аномалий модификации). Цель — достижение структуры, где каждый факт хранится в одном месте.

Основные нормальные формы (НФ):

НФ Условие Цель Пример проблемы (до) Решение (после)
1NF Все значения атрибутов атомарны (неделимы), нет повторяющихся групп. Устранить составные/множественные значения в ячейках. Orders(OrderID, Customer, Product1, Product2, ...) Вынести продукты в отдельную таблицу OrderDetails.
2NF Должна быть 1NF + каждый неключевой атрибут полностью зависит от всего первичного ключа (нет частичных зависимостей). Устранить зависимости от части составного ключа. OrderDetails(OrderID, ProductID, ProductName, Quantity). ProductName зависит только от ProductID. Вынести ProductName в таблицу Products(ProductID, ProductName).
3NF Должна быть 2NF + нет транзитивных зависимостей (неключевые атрибуты не зависят от других неключевых атрибутов). Устранить зависимости между неключевыми полями. Employees(EmpID, DeptID, DeptName, DeptLocation). DeptName и DeptLocation зависят от DeptID. Вынести отдел в таблицу Departments(DeptID, DeptName, DeptLocation).

Пример нормализованной схемы (до 3NF):

-- Избегаем аномалий, храним каждый факт один раз.
CREATE TABLE Customers (CustomerID INT PRIMARY KEY, Name VARCHAR, Email VARCHAR);
CREATE TABLE Products (ProductID INT PRIMARY KEY, Name VARCHAR, Price DECIMAL);
CREATE TABLE Orders (OrderID INT PRIMARY KEY, CustomerID INT REFERENCES Customers(CustomerID), OrderDate DATE);
CREATE TABLE OrderDetails (
    OrderDetailID INT PRIMARY KEY,
    OrderID INT REFERENCES Orders(OrderID),
    ProductID INT REFERENCES Products(ProductID),
    Quantity INT
);

Компромисс: Чрезмерная нормализация может привести к необходимости частых JOIN операций, что ухудшает производительность чтения. Иногда применяется денормализация — сознательное дублирование данных для ускорения запросов.