При проектировании базы данных важно не только создать таблицы и индексы, но и отразить в них бизнес-логику.

Содержание:
1. Зачем документировать процесс проектирования БД
2. От бизнес-требований к логической модели: что записывать
3. Переход к физической модели: как документировать компромиссы
4. Кейс: документирование БД сервиса подписок
5. Инструменты для поддержания документации в актуальном состоянии
6. Заключение
1. Зачем документировать процесс проектирования БД
Первое, что нужно помнить:
Бизнес-требования ≠ схема БД
Документация связывает бизнес-требования и техническую реализацию. Без нее:
-
Разработчики тратят время на reverse engineering.
-
Оптимизации превращаются в костыли.
-
Изменения в БД становятся рискованными.
Рассмотрим на примере (пример №1), когда заказчик говорит: «У пользователя может быть только одна активная подписка». Разработчик создает таблицу subscription с полем is_active.
Что забыли учесть?
-
Поле is_active не гарантирует уникальность. Почему не добавили триггер или ограничение?
-
Как обрабатывать отмену подписки? Нужно ли архивировать данные?
Через год новый разработчик добавляет подписки через INSERT, не проверяя is_active. В итоге у пользователя оказываются две «активные» подписки — баг, который могли бы предотвратить, если бы документация объясняла бизнес-правило.
Еще один пример (пример №2). Требование заказчика: «Пользователь может сменить тариф, но мы должны сохранять историю изменений для аналитики». Разработчик создает таблицы subscription и tariff и добавляет в subscriptions поле tariff_id.
Что пошло не так?
-
История изменений нигде не записывается.
Итог:
-
Через месяц аналитики просят отчет «как часто меняли тарифы», но данных нет.
-
Приходится экстренно править схему, переносить данные.
Чтобы определить, что должно быть в документации для процесса проектирования БД, начнем постепенно заполнять чек-лист.
|
Что должно быть задокументировано |
Пример |
|
Бизнес-сущности и их атрибуты |
Подписка (subscription) — это доступ пользователя к сервису на определенный тариф. Имеет дату начала/окончания. |
|
Ограничения |
У пользователя может быть только одна активная подписка (проверяется триггером check_single_active_subscription). |
|
Причины денормализации |
Поле product_name дублируется в order_items, чтобы сохранять историческое название товара. |
|
Сложные связи |
Таблица tariff связана с tariff_history, но данные в нее попадают через триггер, а не API. |
2. От бизнес-требований к логической модели: что записывать
Перейдем к логической модели. Если представить бизнес-требования как рассказ, то логическая модель — это его грамотный технический пересказ без искажений. Ее главная задача — сохранить смысл требований в структуре БД и четко зафиксировать, почему она устроена именно так.
Ключевые элементы документирования логической модели включают следующее:
-
ER-диаграмма,
-
глоссарий,
-
принятые решения,
-
примеры данных (опционально).
Ниже приведено описание применения этих способов документирования для примера из предыдущего раздела (пример №2).
2.1. ER-диаграммы с пояснениями
Сначала определяются основные сущности по результатам анализа предметной области и бизнес-требований. По ним формируются таблицы, например, user и tariff. Далее проектируются связи между таблицами, на этом этапе могут возникнуть связующие таблицы. Так, для реализации требования хранить несколько изменений в тарифах и даты, когда они произошли, создается таблица tariff_history.
Для реализации нефункциональных требований также могут быть добавлены технические таблицы, например, с логами.
После визуализации результатов анализа, описанного выше, схема проектируемой БД воплощается в виде ER-диаграммы.
Инструменты: DBML, Mermaid, Lucidchart.
2.2. Глоссарий терминов
Для синхронизации терминов и определений на проекте формируется перечень ключевых понятий. Он помогает всем участникам проекта говорить на одном языке.
Список терминов формируется из интервью с заказчиком и из бизнес-требований. Под проект выбирается структура глоссария, для сложных проектов его можно разделить на две таблицы: термины с определениями и справочник таблиц и полей.
Глоссарий дополняет ER-диаграмму. Когда ER-диаграмма показывает связи, глоссарий поясняет значение сущностей в бизнес-контексте.
2.3. Принятые решения
В процессе проектирования систем и БД часто рассматриваются разные варианты реализаций, а затем по определенным причинам выбор делает в пользу одной из них. Важно записать, что повлияло на решение, чтобы не проводить повторные анализы, не потерять контекст и не вернуть случайно ранее отвергнутые варианты.
Принятые решения должны быть описаны в документации, если их появлению предшествовали совещания по проблемным вопросам, необходимость прийти к компромиссам или технические ограничения реализаций.
Пример документирования альтернатив, которые отвергли, и почему:
«Не стали использовать триггер для автоматического создания записей в tariff_change, так как это усложняет отладку. Изменения вносятся явно через API».
Ниже небольшой чек-лист для самопроверки при документировании логической модели.
|
Что должно быть в документации логической модели |
Пример |
|
ER-диаграммы |
Пояснение к схеме: |
|
Глоссарий |
Термин: Смена тарифа. |
|
Список принятых решений |
Вариант: Проверять активную подписку через триггер, а не ограничение с условием. |
|
Примеры данных |
INSERT INTO tariff (tariff_id, tariff_name, tariff_price, is_active) |
3. Переход к физической модели: как документировать компромиссы
После разработки фундамента, логической модели, разрабатываются решения, переводящие ее на язык конкретной СУБД. Эти решения формируют физическую модель, которая фиксирует каждое отклонение от нормализованной структуры с учетом производительности (индексы, денормализация).
Без документации такие решения забываются. Например, в проекте онлайн-магазина электроники через полгода никто не помнит:
-
Почему в таблице orders дублируется customer_name.
-
Зачем добавлен «лишний» индекс.
-
Почему данные хранятся в неоптимальной форме.
Результат — разработчики боятся вносить изменения, а оптимизации превращаются в технический долг. Чтобы избежать потери контекста, каждое неочевидное решение рекомендуется фиксировать в трёх ключевых точках:
-
Код/миграции (SQL-комментарии) — для разработчиков, работающих напрямую с БД.
-
Техническая документация (README/Confluence) — общий архитектурный контекст.
-
Схема данных (ER-диаграммы, описания таблиц) — визуальное отражение решений.
Пример №3: Документирование денормализации
Ситуация:
В идеальной схеме цена товара должна браться из таблицы products. Но возможны случаи, когда цена товара изменилась, а заказ должен сохранить старую стоимость. Для этого в order_items добавляется fixed_price.
Как и где документировать:
1. В SQL-скрипте миграции:

2. В README репозитория:

3. На схеме (например, Mermaid).
Пример №4: Обоснование индексов
Ситуация:
Добавлен составной индекс (user_id, created_at) в таблицу orders.
Как и где документировать:
1. В SQL-комментарии:

2. В документации (Confluence/Notion):
|
Индекс |
Поля |
Назначение |
Эффективность |
|
idx_user_created |
user_id, created_at |
Оптимизация запросов «заказы пользователя за период» |
Снижение времени с 1200 мс до 50 мс |
3. На схеме (например, Mermaid).
Пример №5: JSON-поля вместо реляционной структуры
Ситуация:
Поле metadata в таблице user хранит динамические атрибуты (например, источник регистрации).
Как и где документировать:
1. В SQL-скрипте миграции:

2. Страница в Confluence/Notion — для сложных решений.
Чтобы систематизировать подход, рекомендуется использовать чек-лист для проверки полноты документации. Вот ключевые категории, которые стоит учитывать:
|
Что должно быть задокументировано |
Пример |
|
Архитектурные решения |
|
|
Репликация |
Чтение из реплик для отчетов, запись только в мастер. |
|
Шардирование |
Данные пользователей шардированы по user_id для горизонтального масштабирования. |
|
Решения по оптимизации производительности |
|
|
Партиционирование |
Таблица orders партиционирована по created_at для ускорения архивных запросов. |
|
Оптимизация запросов |
Индекс (user_id, status) ускоряет фильтрацию по активным пользователям. |
|
Административные решения |
|
|
Резервное копирование |
Ежедневные снепшоты с retention 7 дней. |
Для каждого «неидеального» решения рекомендуется указывать:
1. причину (производительность, гибкость, требования),
2. альтернативы (что отвергли и почему),
3. последствия.
4. Кейс: Документирование БД сервиса подписок
Рассмотрим практический пример проектирования БД для сервиса подписок — от бизнес-требований до физической реализации.
Бизнес-требования:
-
Одна активная подписка на пользователя:
Пользователь должен иметь одну активную подписку. -
История изменений тарифов:
При смене тарифа должна сохраняться старая цена для аудита и аналитики. -
Аудит действий:
Система должна фиксировать изменений подписки (создание, продление, отмена) с указанием автора действия.
Логическая модель
ER-диаграмма в Mermaid:

Пояснения к диаграмме:
1. История изменений тарифов
Таблица tariff_history хранит только изменения цены, а не весь тариф, чтобы избежать избыточности.
2. События подписок
Таблица subscription_change фиксирует все действия (создание, отмена, изменение тарифа) для аудита.
Глоссарий терминов:
|
Термин |
Определение |
Источник |
Таблица БД |
|
Подписка |
Доступ пользователя к сервису |
Из бизнес-требования: «Пользователи должны иметь возможность подписываться на сервис» |
subscription |
|
Тариф |
План с ценой и условиями |
Из интервью с Заказчиком |
tariff |
|
Историчность |
Правило хранить все изменения цены |
Из бизнес-требования: «При смене тарифа должна сохраняться старая цена для аудита и аналитики» |
tariff_history |
Физическая модель
1. Денормализация цены в подписку
Проблема:
Цена тарифа может измениться, но стоимость активной подписки должна оставаться неизменной.
Решение:
Добавляем поле current_price в таблицу subscription, дублируя данные из tariff.
Документирование:

2. Триггер для проверки активной подписки
Бизнес-правило: У пользователя может быть только одна активная подписка.
Реализация: через SQL-скрипты.

Пояснение в документации:
Важно: триггер гарантирует соблюдение бизнес-правила. При попытке создать вторую активную подписку возникнет ошибка.
Альтернативы:
-
Проверка на уровне приложения (риск: race condition).
-
Ограничение через частичный индекс (сложность поддержки).
3. История изменений тарифов
Решение:

Почему не JSON?
-
Структура данных предсказуема (цена + метаданные).
-
Упрощает аналитические запросы (фильтрация по дате/пользователю).
Итог
-
Бизнес-правила зафиксированы в:
1.1 SQL-комментариях (триггеры, ограничения).
1.2 Отдельном документе (database_schema.md). -
Компромиссы объяснены:
2.1 Почему выбрана денормализация.
2.2 Почему история тарифов — отдельная таблица. -
Примеры запросов ускоряют onboarding новых разработчиков.
5. Инструменты для поддержания документации в актуальном состоянии
Документирование информации эффективно только в том случае, когда в документации содержится актуальная информация. Есть два основных подхода, которые могут помочь в поддержании ее актуальности.
5.1 Автоматическая генерация документации
Ручное обновление схем и описаний неизбежно приводит к расхождениям между документацией и фактической структурой БД. Современные инструменты позволяют автоматизировать этот процесс.
-
Встроенные средства PgAdmin позволяют экспортировать актуальную структуру таблиц с типами полей, ограничения, индексы, а также SQL-комментарии к объектам БД.
-
Визуализация: позволяет описывать схему в декларативном формате.
5.2 Changelog
Это еще один вариант поддерживать документацию в актуальном состоянии. Например, ведение migrations.md в репозитории с изменениями. А для сложных изменений добавление ссылки на задачи (тикеты) или обсуждения.
В итоге, инструменты помогут сделать документацию более полезной:
-
Автогенерация сэкономит время и снизит риск расхождений.
-
Changelog сохранит контекст изменений для всей команды.
6. Заключение
Проектирование БД — это не только создание таблиц и индексов, но и документирование решений, чтобы разработчики понимали, почему схема устроена именно так, аналитики могли самостоятельно писать запросы, а новые члены команды быстрее входили в проект.
Ключевые шаги:
-
Записывайте бизнес-правила в логической модели (ER-диаграммы, глоссарий).
-
Объясняйте компромиссы в физической реализации (SQL-комментарии, README).
-
Автоматизируйте поддержание документации в актуальном состоянии.
Итог:
Документация — это живой инструмент. Если она встраивается в процесс разработки, то помогает сохранить целостность проекта на всем его жизненном цикле.
ссылка на оригинал статьи https://habr.com/ru/articles/920916/
Добавить комментарий