Skip to content
难度LEVEL★★★★
阅读READ约 3 分钟~3 min
更新UPDATED2026-09

第 5 章 把表设计好 · 关系、外键、索引

easycode · Agent Skill

第一册第 3 章说过,设计表结构,就是想清楚"产品到底要记住什么"。这一章给你三件设计工具,从此 AI 建的表你不光看得懂,还评得动。

工具一,一个事实只存一份。先看反面教材。certificates 表里直接存一列 owner_email 会怎样?用户改一次邮箱,他名下一千张凭证就要改一千处。漏掉一张,数据从此打架,而且你永远不知道哪份是真的。正解你在第三册第 8 章已经见过,certificates 只存 owner_id,邮箱只住在 users 表里,一处修改,处处生效。这条朴素的原则是整个数据库设计的地基,教科书叫它规范化,记住人话版就够。

工具二,外键,让数据库替你守规矩。owner_id 这个"工号"不只是约定,建表时声明出来,数据库会强制它有效。看一张真实形状的建表语句,AI 迁移文件里的那些话,现在全能读了。

sql
create table certificates (
  id uuid primary key default gen_random_uuid(),
  owner_id uuid references users(id) not null,
  status text not null default 'draft',
  created_at timestamptz default now()
);

逐行读。primary key 是每行的身份证,uuid 是一种全球不重复的随机编号,默认自动生成。references users(id) 就是外键,从此想塞一个不存在的 owner_id,数据库直接拒收,它从"记录事实"升级成了"守护事实"。not null 是此列不许空着。default 是没填时的默认值。关系的形态顺带认全。一对多,一个用户多张凭证,外键放"多"的那边。多对多,凭证和标签互相多,需要一张中间表牵线。一对一,少见。

工具三,索引,书后的检索目录。没有索引时,WHERE owner_id = ... 等于逐页翻完整本书。跑一句 create index on certificates(owner_id); 之后,等于直接翻书后目录。代价是写入稍慢,占点空间,所以只给经常用来找的列建。经验法,外键列和高频出现在 WHERE 里的列,主键自带,不用操心。第 8 章你会看到,九成"越用越慢",最后都查到一条缺索引的查询头上。

三件工具合成一个习惯。以后让 AI 建表,需求里先让它回答三问。有哪些"东西"(表)?它们怎么相连(外键)?最常按什么找(索引)?三问入了需求,AI 的建表质量立刻上一个档。

出事时想起我

同一个信息在两处对不上,设计违反了"只存一份"。数据越多越慢,查缺失的索引。删用户时报 violates foreign key constraint,那是数据库在守护事实,他名下还有凭证呢。别硬删,这属于"想清楚再动"的决策,级联删除是把双刃剑,动它之前叫人。

关键领悟

好的表设计三句话。一个事实只存一份。关系交给外键,让数据库强制守护。常走的查找路径铺上索引。

试一试(安全档 · 只读)

打开 Supabase,把我们最重要的两三张表画成一张纸上关系图,方框是表,箭头是外键,箭头旁标上"一对多"。画不出的那根箭头,就是你下次和 AI 开会的第一个议题。

由 Charles Tao 与 Claude 协作写成——这本身就是这套书讲的工作方式。Written by Charles Tao with Claude — which is itself the working method this series teaches. · 许可License