用 AI 做数据建模,正确做法不是让它直接吐一段 CREATE TABLE,而是先让它把业务约束问清楚,再按「实体草案 → 约束逐条确认 → 迁移与回滚 → 种子数据验证」四步落地。跳过前两步,生成的表看着很规范,上线十有八九要返工。
为什么直接让 AI 建表容易返工
大语言模型见过海量开源项目的 schema,它非常擅长输出「看起来像标准答案」的表结构。问题在于,标准答案缺的恰恰是你业务里最要紧的那部分:
- 约束靠猜:唯一性、可空性、级联删除这些,模型不知道你的真实规则,通常按最宽松的写法给。
- 忽略存量数据:新字段加 NOT NULL 却没有默认值,老数据一行都插不进去。
- 时间与删除策略随意:datetime 还是 timestamp 、要不要软删除、金额用 decimal 还是整数分,这些选择一旦错了,改起来是全表迁移。
- 索引拍脑袋:给每个外键都建索引看似稳妥,实际拖慢写入且多数用不上。
数据建模的产出不是 SQL,而是一组「不能被违反的业务规则」。 SQL 只是这组规则的表达形式,先敲定规则再写 SQL,AI 才是加速器而不是添乱源。
四步法:从一句话需求到可迁移表结构
- 第一步:把需求讲成「实体 + 动词」。不要说「做一个订单系统」,要说清楚有哪些主体、它们之间发生了什么动作、动作要留下什么痕迹。这个描述是后面所有步骤的输入,写得太抽象,后面每一步都会放大偏差。
- 第二步:让 AI 出模型草案,并强制它为每条约束给出理由。拿到草案后逐条追问:这个字段为什么可空、这个唯一索引覆盖哪几列、删除父行时子行怎么办。没有理由的约束一律视为待确认。
- 第三步:生成迁移脚本与回滚脚本,成对产出。任何一次 schema 变更都必须同时拿到 up 和 down 两份脚本,且回滚脚本要在本地真实执行过一次。
- 第四步:用种子数据和边界用例反向验证。让 AI 造 20 条正常数据 + 5 条边界数据(超长字符串、重复唯一键、跨时区时间、负数金额、空关联),跑一遍插入看是否按预期报错。
第一步的输入模板
下面这段结构化的需求描述是给模型的输入,比自然语言需求有效得多。方括号里的内容按你的实际业务替换:
业务:社区课程平台
实体:用户、课程、订单、课时
动作:
- 用户 下单 课程(一个订单只含一门课程)
- 订单 支付 后生成 课时 额度(按课程课时数)
- 用户 消耗 课时 预约上课
必须成立的规则:
- 同一用户对同一门课程,最多只能有一笔已支付订单
- 订单金额以分为单位存储,不允许浮点
- 订单删除采用软删除,课时记录不级联删除
- 所有时间字段统一存 UTC,展示时按用户时区转换
数据量预估:订单 10 万级/年,查询以「用户 + 时间范围」为主
第二步的产出与追问
模型拿到上面的输入后,会给出类似这样的草案。你要做的是对着每一条约束追问理由,把「大概」变成「确定」:
| 字段 / 约束 | 草案写法 | 需要追问的点 |
|---|---|---|
| orders.user_id + course_id | 联合唯一索引 | 只约束已支付订单,未支付要允许多笔,需要部分索引而非普通唯一索引 |
| orders.amount | bigint(分) | 退款、优惠分摊后是否可能出现负数,是否需要 CHECK 约束 |
| orders.deleted_at | 可空时间戳 | 唯一索引是否要把软删行排除,否则同一用户重买会失败 |
| lessons.used_at | timestamp | 是否跨时区,展示层谁负责转换 |
追问用的提示词骨架(点击展开)
你是资深数据工程师。基于上面的需求与草案,请:
1. 列出每条约束成立的理由,理由不成立就标注为待确认;
2. 指出哪些字段在存量数据下会导致迁移失败,给出兼容写法;
3. 给出 up / down 两份迁移脚本;
4. 给出 20 条正常 + 5 条边界种子数据,并说明每条边界数据期望的错误。
只输出结论与代码,不要复述我的需求。
第三步:迁移与回滚必须成对
以加字段为例,安全的写法是「加可空字段 → 回填 → 加约束」,而不是一步到位加 NOT NULL:
-- up:分三步,保证每一步都可回滚
ALTER TABLE orders ADD COLUMN paid_at timestamp NULL;
UPDATE orders SET paid_at = created_at WHERE status = 'paid';
-- 数据回填校验通过后再上约束(单独一次发布)
-- ALTER TABLE orders ALTER COLUMN paid_at SET NOT NULL;
-- down
ALTER TABLE orders DROP COLUMN paid_at;
五个高频坑
- 用浮点存金额:让 AI 明确用整数分 + 整型字段,避免 0.1 + 0.2 这类误差进账。
- 枚举用字符串:状态字段建议用短整型加常量映射,或数据库原生 enum,避免大小写混乱。
- 唯一索引没考虑软删除:软删行仍占用唯一键,重名、重买都会被拒。
- 外键与索引混为一谈:外键约束不等于索引,高频查询列要单独评估。
- 迁移脚本没在真实数据量上跑过:十万行加索引在测试库 0.1 秒,线上可能锁表几十秒。
相关阅读:MCP 服务器怎么连数据库:连接池、只读约束与 SQL 安全边界、AI 代码评审清单:让智能体先跑一遍的六道关卡、规格驱动的 AI 开发:先写清需求再让模型动手。
AI 生成的表结构能直接用吗
不能原样上线。把它当成一份写得不错的初稿:业务约束需要你逐条确认,索引需要结合真实查询模式调整,迁移还必须在接近生产的数据量上实测。草稿可以省掉 70% 的打字时间,但省不掉判断。
应该让 AI 直接写 ORM 模型还是原生 SQL
先写原生 SQL 的迁移脚本,再让 AI 翻译成 ORM 模型。原因是迁移脚本更贴近数据库真实行为(部分索引、 CHECK 、时区处理),ORM 层容易把这些细节隐藏掉,直接生成 ORM 经常漏约束。
已有的老表怎么让 AI 参与改造
把 SHOW CREATE TABLE 的结果、慢查询样本、数据量级一起喂给它,让它先输出「现状评估报告」再给改造方案。直接让它改老表,最常见的失败是忽略了线上已有数据的分布。










评论 (0)