Stage 2. Основы ER-диаграмм: проектирование до CREATE TABLE
Новички часто начинают проектирование базы с CREATE TABLE. Кажется, что это продуктивно: создали users, потом orders, потом products, и схема уже существует. Проблема появляется через месяц, когда связи между таблицами непонятны, поля начинают дублироваться, а новая фича требует угадывать, где должны жить данные.
ER-диаграмма помогает избежать этого. Это чертеж базы до ее создания. Сначала вы рисуете бизнес-объекты и связи между ними. Только потом превращаете модель в SQL-таблицы, колонки, внешние ключи и промежуточные таблицы.
Что такое ER-диаграмма
ER означает Entity-Relationship, то есть “сущность-связь”. Диаграмма описывает три базовые вещи:
| Термин ER | Смысл | Во что превращается в SQL |
|---|---|---|
| Entity / сущность | Бизнес-объект предметной области | Таблица |
| Attribute / атрибут | Данные, которые хранятся о сущности | Колонка |
| Relationship / связь | Соединение между сущностями | Foreign key или join table |
Для интернет-магазина типичные сущности — User, Order и Product. На этом этапе это еще не SQL-таблицы. Это объекты предметной области: пользователь делает заказы, заказ содержит товары, товар может встречаться во многих заказах.
Entity: будущая таблица
Сущность — это то, что системе нужно помнить отдельно. User является сущностью, потому что система хранит личность пользователя и контактные данные. Order является сущностью, потому что система хранит событие покупки. Product является сущностью, потому что в каталоге есть товары с названием, ценой и доступностью.
Полезная проверка: можете ли вы одной фразой объяснить ответственность сущности? Если нет, она может быть слишком размытой или смешивать несколько разных понятий.
Attributes: будущие колонки
Атрибуты описывают, какие данные принадлежат сущности. Для User простой набор атрибутов может быть таким:
id;name;email;created_at.
Позже эти атрибуты станут колонками таблицы. ER-диаграмма не обязана содержать каждую техническую деталь финальной миграции, но она должна показывать важные поля модели: идентификаторы, имена, даты, статусы и поля, которые участвуют в связях.
Relationships: самая важная часть
Связи показывают, как записи соединяются друг с другом. Именно здесь у многих новичков появляется понимание, что база данных — это не набор изолированных таблиц.
| Тип | Пример | Как выглядит в БД |
|---|---|---|
| 1:1 | User - Profile | Foreign key в одной из таблиц |
| 1:N | User - Order | orders.user_id указывает на users.id |
| M:N | Order - Product | Промежуточная таблица, например order_products |
Кардинальность — это ответ на вопрос “сколько?”. Не нужно начинать с сухой теории, задавайте практические вопросы. Может ли один пользователь иметь много заказов? Да, значит User к Order — это 1:N. Может ли один заказ содержать много товаров, а один товар встречаться во многих заказах? Да, значит Order к Product — это M:N. В реляционной базе M:N представляется через промежуточную таблицу.
Как ER превращается в SQL
Преобразование прямое:
| ER-модель | SQL-реализация |
|---|---|
| Entity | Table |
| Attribute | Column |
| Relationship | Foreign key |
| M:N relationship | Join table |
Для модели интернет-магазина диаграмма:
User --< Order --< Order_Product >-- Product
превращается в такие таблицы:
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id),
status TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC(10,2) NOT NULL
);
CREATE TABLE order_products (
order_id BIGINT NOT NULL REFERENCES orders(id),
product_id BIGINT NOT NULL REFERENCES products(id),
quantity INTEGER NOT NULL,
price_at_purchase NUMERIC(10,2) NOT NULL,
PRIMARY KEY (order_id, product_id)
);
order_products существует потому, что связь между заказами и товарами — многие-ко-многим. В ней также хранятся факты самой связи: количество и цена на момент покупки. Эти значения не принадлежат только orders или только products; они описывают товар внутри конкретного заказа.
Ошибки, которые предотвращает ER-диаграмма
Без ER-диаграммы типичные ошибки появляются быстро:
- Дублирование данных пользователя или товара в нескольких таблицах.
- Неправильные связи, например хранение только одного товара прямо в
orders. - Сложные будущие
JOIN, потому что внешние ключи неочевидны. - Проблемы с нормализацией, потому что ответственности таблиц не разделены.
- Забытые правила кардинальности и опциональные связи.
Диаграмма не отменяет проектирование, но делает вопросы видимыми до того, как слабая схема попадет в миграции и код приложения.
Инструменты для рисования ER
Для практики начните с простых инструментов:
dbdiagram.ioдля быстрых диаграмм в стиле базы данных;draw.ioдля свободных визуальных схем;- DBeaver для просмотра диаграмм по уже существующей базе.
Выбирайте инструмент, который помогает ясно думать. Важен не сам инструмент, а дисциплина: сначала связи, потом SQL.
Практика перед следующим уроком
Нарисуйте небольшую ER-диаграмму для блога: User, Post, Comment и Tag. Решите, какие связи будут 1:N, а какие M:N. Затем напишите список таблиц, который получится из диаграммы. Если вы можете объяснить каждый внешний ключ простыми словами, диаграмма полезна.
Главная мысль: ER-диаграмма — это момент, когда база данных проектируется головой, а не только руками. Сначала связи на бумаге — потом таблицы в БД.