~/VibeHandbook
$39

09 · 03

Schema 设计基础

schema 是你数据的蓝图:存在哪些表、它们有哪些列,以及它们如何关联。好的 schema 设计大多是常识加上几个习惯。

  • 每一种"东西"对应一张表。 用户、帖子、订单——各自拥有自己的表。
  • 每一行都需要一个唯一的 ID(一个主键)。
  • 用外键链接表,而不是到处复制数据。
  • 选择诚实的类型。 金钱是 decimal,不是 float。日期是时间戳,不是文本。
  • 不要重复。 如果一个用户的邮箱存在于五张表里,你最终会有五个不同的邮箱。

下面是一个博客的简单 schema,正是 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 NULLUNIQUE 约束。这些是数据库为你强制执行的护栏,所以即使你的代码有 bug,坏数据也无法溜进来。

一个值得有意添加的约束,是当父记录消失时会发生什么。默认情况下,删除一个仍被帖子引用的用户会失败——而这往往正是你想要的。但你可以显式指定:REFERENCES users(id) ON DELETE CASCADE 会把帖子也一并删除,而 ON DELETE RESTRICT 会阻止该删除。有意去选,胜过在生产环境里以惨痛方式发现默认行为。同样的"让数据库保护你"的直觉也适用于 CHECK 约束(CHECK (price >= 0))——它在源头拒绝荒谬的数据,而不是去信任每一条代码路径都会做校验。

想离线阅读?

获取 PDF + EPUB + 可下载的提示词库 + 版本更新。

$ 获取 PDF — $39