Skip to content
PПромтбук
RUEN
04База данных

Дизайн схемы БД

Таблицы, отношения, ключи, индексы — схема которую легко эволюционировать.

Спроектируй схему БД для {{domain}} в {{db}}.

Шаги

1. Сущности

Список с описанием в одну строку. Существительные единственного числа:

User       — человек который пользуется приложением
Project    — рабочая папка пользователя
Document   — файл внутри проекта
Comment    — обсуждение под документом
Invitation — приглашение нового участника

2. Отношения

Какие связи между сущностями:

User ──< Project ──< Document ──< Comment
                ↓
            Invitation

Для каждой связи: 1:1, 1:N, N:N?

3. Колонки

Для каждой таблицы:

CREATE TABLE projects (
  id            BIGSERIAL PRIMARY KEY,
  owner_id      BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  slug          TEXT NOT NULL,
  name          TEXT NOT NULL,
  description   TEXT,
  is_public     BOOLEAN NOT NULL DEFAULT false,
  created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  archived_at   TIMESTAMPTZ,

  UNIQUE (owner_id, slug)
);

Правила

  • ID: всегда; BIGSERIAL / UUID v7 (см. ниже)
  • created_at, updated_at: всегда timestamptz, NOT NULL, DEFAULT now()
  • Soft delete: archived_at или deleted_at вместо физического DELETE
  • NULL — только если поле реально опциональное
  • Default'ы на boolean'ах и enum'ах

4. Ключи

Primary key — что выбрать

ТипПлюсыМинусы
BIGSERIAL (auto-inc int)Маленький, sortableРаскрывает счётчик (security), не подходит для распределённых
UUID v4Уникален глобально, безопасенНе sortable, дольше index
UUID v7 / ULIDsortable + safe + распределяетПоддержка в БД ограничена
Custom (u_abc123)Читаемо для людейСложнее, нужна генерация

Для большинства проектов: UUID v7 или BIGSERIAL для внутренних + nanoid для публичного.

Foreign keys — всегда явно, с ON DELETE:

owner_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE

Варианты ON DELETE:

  • CASCADE — удаление родителя удаляет детей (часто опасно)
  • SET NULL — обнуляет ссылку
  • RESTRICT — запрещает удаление если есть дети (безопасно по умолчанию)

5. Индексы

Не индексируй "на всякий случай" — каждый индекс замедляет writes.

Индексируй:

  • Все foreign keys (часто JOIN'ят)
  • Колонки по которым WHERE / ORDER BY / GROUP BY на горячих запросах
  • Колонки в UNIQUE constraints (автомат)

Composite индекс — порядок имеет значение. WHERE используется первым:

CREATE INDEX idx_documents_project_created
  ON documents (project_id, created_at DESC);

Partial indexes для частых случаев:

CREATE INDEX idx_active_users ON users (created_at) WHERE archived_at IS NULL;

6. Constraints

  • NOT NULL — где можно
  • CHECK — для бизнес-правил (CHECK (price >= 0))
  • UNIQUE — комбинации которые должны быть уникальны
  • Foreign keys — всегда

7. Нормализация vs денормализация

Стартуй с 3NF (нормализация). Денормализуй точечно:

  • Если запрос требует 5+ JOIN и тормозит → выноси кешируемые поля
  • document.comment_count — рассчитываемое поле; обновляй триггером или приложением

8. Аудит и история

Опции:

  • updated_at + триггер обновления — минимум
  • Audit table (document_history) — для требований compliance
  • Event sourcing — если нужна полная история состояний

9. Soft delete

archived_at TIMESTAMPTZ

Все запросы фильтруют WHERE archived_at IS NULL — обернуть во view или ORM-фильтр.

10. Миграции

  • Каждое изменение — отдельная миграция
  • Forward-only (не делай down если не уверен)
  • Большие изменения — поэтапно (см. отдельный промт "Безопасная миграция БД")

Анти-паттерны

  • id INT (signed!) — переполнится через 2 миллиарда
  • varchar(255) без причины — используй text (в Postgres одно и то же)
  • ❌ Хранение JSON где можно колонки — не индексируется, не валидируется
  • status TEXT без CHECK — мусор будет
  • ❌ Нет created_at — будешь жалеть когда дебажишь
  • ❌ Удаление DELETE вместо soft — потеряешь данные

В конце

  • DDL для всех таблиц
  • Диаграмма (текстовая)
  • Индексы с обоснованием
  • Список миграций (если эволюционируешь существующую)
К подразделу «База данных»
Похожие промты