ERD на собеседовании системного аналитика

Готовишься к собесу системного аналитика?
827 вопросов: REST, UML, OAuth, ERD, требования. Тренируйся в Telegram
Тренировать SA в Telegram

Зачем ERD знать СА

ERD — основной инструмент СА для проектирования модели данных. Без чёткого ERD ТЗ для разработчика становится двусмысленным: непонятно, как связаны сущности, какие связи обязательные, какие могут быть пустыми.

На собесе типичные задачи:

  • Спроектировать ERD для бизнес-домена (заказ, маркетплейс, банк)
  • Найти проблемы в чужом ERD
  • Объяснить, когда нормализовать, когда денормализовать

Сущности и атрибуты

Сущность — объект бизнес-домена (User, Order, Product). В ERD — прямоугольник.

Атрибут — характеристика сущности (User.email, Order.amount). В ERD — внутри прямоугольника.

Первичный ключ (PK) — уникальный идентификатор записи. Подчёркивается или помечается ключиком.

Виды атрибутов:

  • Простой — один scalar (email)
  • Составной — несколько частей (full_name = first_name + last_name)
  • Производный — вычисляется из других (age из birth_date)
  • Множественный — несколько значений на одну сущность (хобби) — обычно выносится в отдельную таблицу

Связи и кардинальность

Связь — как сущности соотносятся.

1:1

Один к одному. Пример: User и UserProfile (если профиль строго один на юзера).

Реализуется через FK на одной из сторон.

1:N

Один ко многим. Пример: Customer и Orders.

FK на стороне «многих»: Order.customer_id → Customer.id.

N:N

Многие ко многим. Пример: Students и Courses.

Реализуется через промежуточную (associative) таблицу: StudentCourse(student_id, course_id).

Обязательность

Связь может быть обязательной с одной или обеих сторон:

  • У каждого Order должен быть Customer (обязательно с обеих сторон)
  • У Customer может не быть Orders (необязательно со стороны Customer)

В Crow's Foot:

  • Одна линия — обязательно
  • Кружок (или две линии) — zero or one
  • «Ножки» крокодила — many

Пример: Customer ||━━━<{ Order читается как «у Customer обязательно ноль или больше Orders».

Нотации Чена и Crow's Foot

Чен (Chen)

  • Сущности — прямоугольники
  • Атрибуты — овалы (рисуются вокруг сущности)
  • Связи — ромбы между сущностями
  • Кардинальность — числа над линиями (1, N, M)

Используется в учебниках. На практике редко.

Crow's Foot (Information Engineering)

  • Сущности — прямоугольники с атрибутами внутри
  • Связи — линии с символами кардинальности на концах

Используется в большинстве инструментов (draw.io, dbdiagram.io, PlantUML). На собесе предполагается по умолчанию.

Готовишься к собесу системного аналитика?
827 вопросов: REST, UML, OAuth, ERD, требования. Тренируйся в Telegram
Тренировать SA в Telegram

Нормализация

Процесс приведения схемы к форме без избыточности.

1NF

Атомарные значения. Нет повторяющихся групп.

Плохо: User.phones = ["+79991234567", "+79997654321"] Хорошо: отдельная таблица UserPhone.

2NF

1NF + все non-key атрибуты зависят от полного primary key (важно для составных PK).

Плохо: OrderItem(order_id, product_id, product_name) — product_name зависит только от product_id, не от полного ключа. Хорошо: OrderItem(order_id, product_id, quantity), Product(id, name).

3NF

2NF + нет транзитивных зависимостей (non-key атрибут не зависит от другого non-key).

Плохо: Order(id, customer_id, customer_email) — customer_email зависит от customer_id, не от order.id. Хорошо: Order(id, customer_id), Customer(id, email).

BCNF

Усиление 3NF. Каждая нетривиальная зависимость идёт от суперключа.

На практике 3NF и BCNF почти идентичны. Достаточно знать 1-3NF на собесе.

Когда денормализуют

Нормализация — для целостности данных. Денормализация — для скорости чтения. Конфликт.

Денормализуют, когда:

  • Много JOIN на горячем пути
  • Read-heavy сценарий
  • Аналитические таблицы (DWH часто полностью денормализован — star schema)

Проектирование схемы под задачу

На собесе типичная задача: «Спроектируй БД для маркетплейса» или «для системы доставки».

Подход:

  1. Слушай сценарии: какие действия в системе? Кто их делает?
  2. Выпиши сущности: User, Product, Order, OrderItem, Address, Payment, Review
  3. Опиши связи: User имеет много Orders, Order содержит OrderItems, OrderItem ссылается на Product
  4. Кардинальность: 1:1, 1:N, N:N? Обязательно или нет?
  5. Атрибуты: какие колонки нужны? Какие типы?
  6. Edge cases: что если Product удалён, а Order на него есть? Что с историей?

Пример для маркетплейса (минимум):

  • User(id, email, created_at)
  • Product(id, name, price, seller_id → User)
  • Order(id, buyer_id → User, status, total, created_at)
  • OrderItem(order_id → Order, product_id → Product, quantity, price_at_purchase)
  • Address(id, user_id → User, street, city, zip)

Заметьте price_at_purchase в OrderItem — это денормализация для сохранения цены на момент заказа (Product.price может потом измениться).

Частые ошибки

Игнорировать историчность. Если цена Product меняется, а в Order сохраняется только product_id — для исторического заказа нельзя восстановить цену. Используйте SCD или денормализацию.

Soft delete без подумать. Удалять Product физически — сломаются Orders, ссылающиеся на него. Альтернативы: soft delete (is_deleted), архивная таблица, запрет на удаление пока есть связанные данные.

Слишком сильная нормализация. «Каждое значение в отдельной таблице» = JOIN-кошмар. 3NF обычно достаточна.

Не указывать тип атрибута. На собесе попросят: «Какой тип у Order.created_at?» Если отвечаете «дата» — мало. Нужно TIMESTAMP WITH TIME ZONE или TIMESTAMPTZ.

Не подумать про индексы. На собесе СА индексы часто пропускают, но они влияют на дизайн. Кандидат, который пометил индексируемые колонки — плюс.

FAQ

dbdiagram.io vs draw.io — что выбрать?

dbdiagram.io лучше для ERD: текстовый DSL, автоматическая визуализация, легко поделиться. draw.io универсальнее, но рисуется руками.

Сколько ERD спроектировать перед собесом?

3-5 для разных доменов: маркетплейс, банк, доставка, образовательная платформа. Тренируйтесь по таймеру, 30 минут на ERD.

Это официальная информация?

Нет. Статья основана на классических работах Чена и опыте кандидатов.