~/VibeHandbook

Глава 09 · 03

Основы проектирования схемы

Схема — это чертёж ваших данных: какие таблицы существуют, какие у них столбцы и как они связаны. Хорошее проектирование схемы — это в основном здравый смысл плюс несколько привычек.

  • Одна таблица на «сущность». Пользователи, посты, заказы — каждое получает свою таблицу.
  • Каждой строке нужен уникальный ID (первичный ключ).
  • Связывайте таблицы внешними ключами, а не копированием данных туда-сюда.
  • Выбирайте честные типы. Деньги — это decimal, а не float. Даты — это временные метки, а не текст.
  • Не дублируйте. Если email пользователя живёт в пяти таблицах, в конце концов у вас будет пять разных email.

Вот простая схема для блога — такая, какую AI сгенерирует для вас:

CREATE TABLE users (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email       TEXT NOT NULL UNIQUE,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE posts (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    author_id   UUID NOT NULL REFERENCES users(id),
    title       TEXT NOT NULL,
    body        TEXT NOT NULL,
    published   BOOLEAN NOT NULL DEFAULT false,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_posts_author ON posts(author_id);

Обратите внимание на REFERENCES (внешний ключ, привязывающий пост к реальному пользователю) и ограничения NOT NULL и UNIQUE. Это страховочные барьеры, которые база данных обеспечивает за вас, так что плохие данные не смогут проскользнуть, даже когда в вашем коде есть баг.

Ограничение, которое стоит добавлять осознанно, — это что происходит, когда родитель исчезает. По умолчанию удаление пользователя, на которого всё ещё ссылаются его посты, завершится ошибкой — что часто и есть то, чего вы хотите. Но можно задать явно: REFERENCES users(id) ON DELETE CASCADE удалит и посты тоже, а ON DELETE RESTRICT заблокирует удаление. Выбрать намеренно лучше, чем узнать поведение по умолчанию болезненным путём в продакшене. Тот же инстинкт «пусть база данных защитит вас» применим к ограничению CHECK (CHECK (price >= 0)) — оно отвергает бессмысленные данные у источника, вместо того чтобы доверять валидации в каждом пути кода.

Хотите офлайн-версию?

Получите PDF + EPUB + скачиваемую библиотеку промптов + обновления версий.

$ Получить PDF — $39