Skip to content

Latest commit

 

History

History
203 lines (139 loc) · 10.4 KB

File metadata and controls

203 lines (139 loc) · 10.4 KB

← 模块首页 · ← 上一章: 互联网是怎么工作的 · 下一章: 请求的生命周期 →

02: 数据建模 — 最高杠杆的技能

一句话:在写任何代码之前,先想清楚你要存什么数据、数据之间是什么关系。

为什么这是最重要的一课

"If we can get this part right, the rest of the code practically writes itself."

(如果我们能把数据建模做对,剩下的代码几乎是自动写出来的。)

这句话在传统开发中就已经是真理。在 Coding Agent 时代,它的分量增加了十倍。

为什么?因为 AI 特别擅长根据数据结构来生成代码。你给 AI 一个清晰的数据模型——有哪些表、每张表有哪些字段、表之间是什么关系——AI 就能自动生成增删改查的接口、表单页面、数据校验逻辑。但如果你的数据模型是错的,AI 生成的一切都会建立在一个有裂缝的地基上。

一个正确的数据模型,是你能给 Coding Agent 的最高杠杆输入。

核心心智模型

"名词变成表"方法

数据建模听起来很抽象,但方法非常简单:

  1. 列出你的应用里的核心名词 — 用户、文章、评论、订单、商品、标签……
  2. 每个名词 = 一张数据表 — User 表、Article 表、Comment 表……
  3. 每张表的列 = 这个名词的属性 — User 表有 name、email、password;Article 表有 title、body、published_at

就这样。数据建模的第一步不是画 ER 图、不是写 SQL,而是用日常语言列出你的应用里有哪些"东西"。

试一试:想想你日常用的任何一个应用——微信、淘宝、抖音。列出它的核心名词。你会发现,虽然界面天差地别,但底层的数据结构都是"名词 + 属性 + 关系"。

"纸质表格测试"

这是检验数据模型是否正确的最朴素方法:

  1. 在纸上画出你的每张表,像 Excel 那样,列头是字段名
  2. 填上几行示例数据(真实的、具体的数据,不是"xxx")
  3. 用手指模拟查询:"我想查张三发布的所有文章"——你能从这些表里找到吗?
  4. 再试:"我想看某篇文章的所有评论"——找得到吗?
  5. 如果找不到,说明你缺了某个字段或某个关系

如果你手动能查到想要的数据,说明数据模型是对的。如果查不到,问题一定出在表的设计上——要么缺了某张表,要么缺了某个关联字段。

这个测试看起来很"低技术",但它比任何建模工具都有效。因为它迫使你用真实数据去验证,而不是在抽象概念里打转。

关系类型

数据之间的关系只有三种。记住这三种,你就能建模 95% 的应用:

一对多(One-to-Many)

一个用户有多篇文章,但每篇文章只属于一个用户。

怎么实现?在"多"的那一方加一个外键(Foreign Key)。文章表里加一个 user_id 列,指向用户表的 id

用户表 (Users)              文章表 (Articles)
┌────┬──────┐              ┌────┬──────────┬─────────┐
│ id │ name │              │ id │ title    │ user_id │
├────┼──────┤              ├────┼──────────┼─────────┤
│ 1  │ 张三 │              │ 1  │ 第一篇   │ 1       │
│ 2  │ 李四 │              │ 2  │ 第二篇   │ 1       │
└────┴──────┘              │ 3  │ 第三篇   │ 2       │
                           └────┴──────────┴─────────┘

张三(id=1)有两篇文章,李四(id=2)有一篇。通过 user_id 就能查到。

多对多(Many-to-Many)

一个学生选多门课,一门课有多个学生。

这时候不能简单地在一方加外键。你需要一张中间表(Join Table),专门记录"谁选了哪门课":

学生表              选课表 (Enrollments)       课程表
┌────┬──────┐      ┌────┬────────────┬───────────┐      ┌────┬────────┐
│ id │ name │      │ id │ student_id │ course_id │      │ id │ name   │
├────┼──────┤      ├────┼────────────┼───────────┤      ├────┼────────┤
│ 1  │ 张三 │      │ 1  │ 1          │ 1         │      │ 1  │ 数学   │
│ 2  │ 李四 │      │ 2  │ 1          │ 2         │      │ 2  │ 英语   │
└────┴──────┘      │ 3  │ 2          │ 1         │      └────┴────────┘
                   └────┴────────────┴───────────┘

张三选了数学和英语,李四选了数学。中间表就是那个"粘合剂"。

一对一(One-to-One)

一个用户有一份个人档案。相对少见,但偶尔会用到。处理方式和一对多类似——在其中一方加外键,但必须加上唯一性约束(Unique Constraint),确保每个用户只能有一份档案。没有唯一性约束的话,它实际上就变成了一对多。

判断关系的黄金问题

面对任意两个名词,问自己两个问题:

"一个 X 能有多个 Y 吗?一个 Y 能有多个 X 吗?"

X → 多个 Y? Y → 多个 X? 关系类型
一对一
一对多(X 是"一",Y 是"多")
一对多(Y 是"一",X 是"多")
多对多

每次遇到新的名词关系,用这两个问题一测,答案立刻出来。

常见误区

误区 1:"先写代码再想数据结构"

这是最常见的错误。很多人上来就让 AI 写页面、写功能,结果做到一半发现数据存不对,只好推翻重来。数据结构决定一切。先用 5 分钟想清楚名词、属性、关系,后面能省几个小时的返工。

误区 2:"表越多越好"或"越少越好"

表的数量不是目标,每个独立的名词一张表才是原则。不要把不同的东西硬塞进一张表(比如把"用户"和"订单"放在一起),也不要把一个东西拆成多张表(比如把用户的基本信息和联系方式分成两张表,除非有特殊理由)。

误区 3:"AI 会帮我设计数据模型"

AI 可以建议数据模型,但只有你才理解你的业务领域。"一个老师能教多门课吗?"这种问题取决于你的业务规则,不取决于技术。如果你在教培机构,一个老师可能只教一门课;如果你在大学,一个老师通常教多门课。AI 不知道你的具体情况,你知道。

练习:用你自己的项目试一试

试着为一个读书笔记应用做数据建模:

第一步:列出名词

  • 用户(User)
  • 书(Book)
  • 笔记(Note)
  • 标签(Tag)

第二步:列出属性

  • User:name、email、password
  • Book:title、author、isbn
  • Note:content、page_number、created_at
  • Tag:name

第三步:用黄金问题判断关系

  • 一个用户能有多本书吗?是。一本书能属于多个用户吗?是。→ 多对多(需要中间表,比如 UserBook)
  • 一本书能有多条笔记吗?是。一条笔记能属于多本书吗?否。→ 一对多(Note 加 book_id)
  • 一条笔记能有多个标签吗?是。一个标签能属于多条笔记吗?是。→ 多对多(需要中间表 NoteTag)
  • 一个用户能有多条笔记吗?是。一条笔记能属于多个用户吗?否。→ 一对多(Note 加 user_id)

第四步:纸质表格测试

在纸上画出这些表,填上几行数据,试试能不能查到"张三在《思考,快与慢》这本书上写的所有笔记"。如果能查到,数据模型就是对的。

动手试一试

在线 SQL 练习:亲手建表查询

打开 SQLiteOnline — 浏览器里直接写 SQL,不需要安装任何东西:

  1. 建一张用户表(复制粘贴到左侧编辑器,点 Run):
CREATE TABLE users (
  id INTEGER PRIMARY KEY,
  name TEXT,
  email TEXT
);
INSERT INTO users VALUES (1, '张三', 'zhang@example.com');
INSERT INTO users VALUES (2, '李四', 'li@example.com');
SELECT * FROM users;
  1. 建一张文章表,体验外键关联
CREATE TABLE articles (
  id INTEGER PRIMARY KEY,
  title TEXT,
  user_id INTEGER
);
INSERT INTO articles VALUES (1, '第一篇文章', 1);
INSERT INTO articles VALUES (2, '第二篇文章', 1);
INSERT INTO articles VALUES (3, '第三篇文章', 2);
SELECT * FROM articles WHERE user_id = 1;

最后一行查询的意思是:"查找张三(id=1)的所有文章"。运行看看结果。

  1. 试试连表查询
SELECT users.name, articles.title
FROM articles
JOIN users ON articles.user_id = users.id;

这就是把两张表"连"起来,同时看到作者名字和文章标题。

这些 SQL 你不需要背。重要的是亲手跑一遍,体会"表"和"关系"在真实数据库中是怎么工作的。

这个概念在 Agentic Coding 中的应用

数据建模是你与 Coding Agent 协作的起点。实际操作建议:

  1. 先描述数据模型,再描述功能 — 给 AI 的 prompt 中,第一段就应该是数据模型:"这个应用有四张表:User、Book、Note、Tag,关系如下……"。然后再说功能需求。这是最高效的沟通方式。
  2. 把数据模型写进 CLAUDE.md — 如果你用 Claude Code,在项目的 CLAUDE.md 文件中明确写出数据模型。这样 AI 在整个开发过程中都有一致的参照。(参见 Agentic Coding Week 4
  3. 数据模型变了,所有代码都要跟着变 — 如果你中途发现某个关系类型判断错了(比如把一对多误判为一对一),要立刻修正。越早修正代价越小。

下一步

03: 请求的生命周期(RCAV 模式)


← 上一章: 互联网是怎么工作的 · 下一章: 请求的生命周期 →