Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Нормализация Базы Данных
Нормализация — это процесс организации данных в базе данных с целью избежать дублирования, обеспечить целостность данных и оптимизировать производительность. Нормализация разбивает большие таблицы на меньшие, связанные между собой таблицы через иностранные ключи.
Зачем нужна нормализация
// ❌ Не нормализованная таблица — много проблем
CREATE TABLE orders (
id INT,
customer_name VARCHAR(100),
customer_email VARCHAR(100),
customer_phone VARCHAR(20),
product_name VARCHAR(100),
product_price DECIMAL(10,2),
product_category VARCHAR(50),
order_date DATE
);
// Проблемы:
// - Дублирование (один покупатель = много строк с теми же данными)
// - Аномалия обновления (изменил email в одной строке, забыл в другой)
// - Аномалия удаления (удалил заказ, потеряли инфо о покупателе)
// - Неправильное удаление (удалили последний заказ покупателя, потеряли его данные)
Нормальные формы (Normal Forms)
1NF (Первая нормальная форма)
Требование: Все данные атомарные (неделимые), нет повторяющихся групп.
// ❌ Нарушает 1NF
CREATE TABLE users (
id INT,
name VARCHAR(100),
phone_numbers VARCHAR(500) // "1234567, 9876543" — не атомарное!
);
// ✅ Соблюдает 1NF
CREATE TABLE users (
id INT,
name VARCHAR(100)
);
CREATE TABLE user_phones (
id INT,
user_id INT,
phone_number VARCHAR(20),
FOREIGN KEY (user_id) REFERENCES users(id)
);
2NF (Вторая нормальная форма)
Требование: 1NF + все неключевые атрибуты полностью зависят от первичного ключа (без частичных зависимостей).
// ❌ Нарушает 2NF
CREATE TABLE student_courses (
student_id INT,
course_id INT,
professor_name VARCHAR(100), // зависит только от course_id, не от student_id!
grade DECIMAL(3,2),
PRIMARY KEY (student_id, course_id)
);
// ✅ Соблюдает 2NF
CREATE TABLE student_courses (
student_id INT,
course_id INT,
grade DECIMAL(3,2),
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (course_id) REFERENCES courses(id)
);
CREATE TABLE courses (
id INT PRIMARY KEY,
name VARCHAR(100),
professor_name VARCHAR(100)
);
3NF (Третья нормальная форма)
Требование: 2NF + нет транзитивных зависимостей (неключевые атрибуты зависят только от первичного ключа).
// ❌ Нарушает 3NF
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
customer_city VARCHAR(100),
city_postal_code VARCHAR(10) // зависит от city, а не от order_id!
);
// ✅ Соблюдает 3NF
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
city_id INT,
FOREIGN KEY (customer_id) REFERENCES customers(id),
FOREIGN KEY (city_id) REFERENCES cities(id)
);
CREATE TABLE cities (
id INT PRIMARY KEY,
name VARCHAR(100),
postal_code VARCHAR(10)
);
Нормализованная структура (пример e-commerce)
// ✅ Хорошо спроектированная БД
CREATE TABLE customers (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP
);
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
price DECIMAL(10,2),
category_id INT,
FOREIGN KEY (category_id) REFERENCES categories(id)
);
CREATE TABLE categories (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100)
);
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
CREATE TABLE order_items (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT,
product_id INT,
quantity INT,
price DECIMAL(10,2),
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
Преимущества нормализации
- Избежать дублирования — каждое данное хранится один раз
- Целостность данных — сложнее внести ошибку
- Легче обновлять — меняешь данные в одном месте
- Экономия места — нет дублирования
- Быстрые запросы — правильная индексация
Недостатки нормализации
- Сложные запросы — много джойнов, может быть медленно
- Производительность — иногда денормализация быстрее
- Сложность — больше таблиц, сложнее понять структуру
Денормализация (когда нужна)
Иногда для производительности делают частичную денормализацию — хранят закэшированные значения:
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
total_amount DECIMAL(10,2), // закэшировано из order_items
customer_name VARCHAR(100), // дублировано для быстрого доступа
FOREIGN KEY (customer_id) REFERENCES customers(id)
);