Ответ
Нормализация — это процесс проектирования схемы реляционной базы данных для минимизации избыточности данных и аномалий при вставке, обновлении или удалении. Основная цель — обеспечение целостности данных.
Основные нормальные формы:
- 1NF (Первая нормальная форма): Устранить повторяющиеся группы. Все значения в столбцах атомарны (неделимы), каждая запись уникальна.
- 2NF (Вторая нормальная форма): Должна выполняться 1NF. Устранить частичные зависимости — все неключевые атрибуты должны полностью зависеть от всего первичного ключа (а не от его части).
- 3NF (Третья нормальная форма): Должна выполняться 2NF. Устранить транзитивные зависимости — неключевые атрибуты не должны зависеть от других неключевых атрибутов.
Пример на Node.js с PostgreSQL:
-- Денормализованная таблица (проблемы: дублирование, аномалии обновления)
CREATE TABLE denormalized_orders (
order_id INT,
customer_name VARCHAR,
customer_email VARCHAR,
product_name VARCHAR,
product_price DECIMAL
);
-- Нормализованная схема (3NF)
CREATE TABLE customers (
customer_id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
email VARCHAR UNIQUE NOT NULL
);
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
price DECIMAL NOT NULL
);
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(customer_id) ON DELETE CASCADE,
order_date TIMESTAMP DEFAULT NOW()
);
CREATE TABLE order_items (
order_id INT REFERENCES orders(order_id) ON DELETE CASCADE,
product_id INT REFERENCES products(product_id),
quantity INT NOT NULL,
PRIMARY KEY (order_id, product_id)
);
Практическое применение в Node.js: При работе с ORM, например, Sequelize, нормализация отражается в моделях и связях:
// Модели Sequelize, соответствующие нормализованной схеме
const Customer = sequelize.define('Customer', { name: DataTypes.STRING, email: DataTypes.STRING });
const Product = sequelize.define('Product', { name: DataTypes.STRING, price: DataTypes.DECIMAL });
const Order = sequelize.define('Order', { date: DataTypes.DATE });
const OrderItem = sequelize.define('OrderItem', { quantity: DataTypes.INTEGER });
// Определение связей
Customer.hasMany(Order);
Order.belongsTo(Customer);
Order.belongsToMany(Product, { through: OrderItem });
Product.belongsToMany(Order, { through: OrderItem });
Преимущества: Целостность данных, эффективное использование памяти, упрощение операций обновления. Недостаток: Усложнение запросов из-за необходимости частых JOIN, что может влиять на производительность для сложных выборок.
Видео-ответы
▶
▶
▶