一句话结论
数据库迁移可以交给 AI 写,但顺序得反过来:先让它出回滚脚本和验证 SQL,再补正向脚本,一步对一步编号。
这篇解决什么问题
上周给订单表加一个渠道字段,需求单只有三行,写脚本加上想清楚怎么撤,占了大半天。适用:MySQL 或 PostgreSQL 的表结构变更,尤其是加列、改字段类型、加索引这类要上线又不能出事的改动。不适用:跨库数据迁移、分库分表重分布这种要停机窗口、要专门工具的大工程。
开始前要准备什么
- DeepSeek 网页版,免费额度够跑完这篇的对话量
- Cursor 用来改脚本和跑终端,免费额度可覆盖,重度用需付费
- 本地 Docker 起一个 MySQL 8.0 实例,专门用来演练
- 一份变更需求原文,写清表名、字段、行数量级
- 相关表的建表语句,也就是 SHOW CREATE TABLE 的结果
- 预计耗时:单表变更通常 30 到 60 分钟,含本地演练
具体怎么做
第 1 步 · 把需求整理成结构化输入
别急着要 SQL。先让它把需求翻译成变更项清单,这一步决定了后面脚本的完整度。我在实操中发现,跳过这步直接要代码,十有八九会漏掉回填和锁表风险。
你是资深 MySQL DBA。下面是一次表结构变更的需求原文,请先别写 SQL,只做三件事:1) 把需求拆成按依赖排序的变更项清单,每项写清表名、列名、类型、是否可空、默认值;2) 标出每项对现有数据的影响,包括是否需要回填、是否需要重建索引、是否会锁表;3) 列出这次变更可能波及的上游查询和定时任务。
需求原文:在 shop_demo 库做两处调整。t_order 增加 channel_code varchar(16) 非空默认 ‘web’,并对 channel_code 和 created_at 建联合索引;t_user_profile 的 phone 从 varchar(32) 改为 varchar(64),允许为空。t_order 约 800 万行,t_user_profile 约 120 万行,MySQL 8.0.32,InnoDB。
输出用表格,这一轮不要给 SQL。
预期产出:一张按依赖排序的变更项表,每行标出锁表风险和回填范围。
第 2 步 · 先要一份回滚脚本
顺序很关键。回滚是”从目标态退回原态”,先把退路定死,正向脚本才有明确的对照物。反过来做的话,回滚基本是倒着编的,编号对不上还容易漏项。
基于上一步的变更清单,现在只写回滚脚本,不要写正向脚本。约束:1) MySQL 8.0 语法,每条语句能单独执行,不要用一个大事务把整体包住;2) 每条 SQL 上方加一行注释,写明它撤销的是哪一项变更、什么情况下必须执行;3) 不可逆操作单独列出来,比如把字段从 varchar(64) 收回 varchar(32) 或者删列,先给一条执行前的检查 SQL;4) 回滚顺序就是正向顺序的逆序,编号用 R1、R2、R3 对应变更项。
输出三段。第一段三行内说明回滚顺序与适用场景。第二段是完整 SQL。第三段是回滚后的自检 SQL,用来确认表结构确实回到了变更前的状态。
预期产出:一份逆序排列的回滚 SQL,外加一段回滚后的结构自检语句。
第 3 步 · 再补正向脚本,编号对齐
这一步要把算法选项钉死。加列走 INSTANT 还是 COPY,差别可能是秒级和分钟级。AI 默认不会主动说,你得点名要它给判断。
现在写正向迁移脚本。要求:1) 每条和上一步的回滚脚本一一对应,编号用 P1、P2、P3 对应 R1、R2、R3;2) t_order 加列用 ALGORITHM=INSTANT,如果你判断我的版本不支持,直接说明并给降级写法;3) 联合索引用 CREATE INDEX,带上 ALGORITHM=INPLACE, LOCK=NONE;4) phone 扩长用 MODIFY COLUMN,明确告诉我这次会不会走 COPY 算法、大致影响多久;5) 脚本要能重复执行,加列加索引之前先查 information_schema 判断是否已存在,把判断 SQL 也写出来;6) 不要出现 DROP TABLE 和 TRUNCATE。
输出带编号的 SQL 代码块,每个编号后面跟一行中文说明。
预期产出:编号与回滚一一对应的正向脚本,每个编号带一行执行说明。
第 4 步 · 让它写验证 SQL
脚本能跑不等于迁移成功。真正要确认的是:默认值有没有覆盖到历史行。下面这段我特意要求分三段,就是为了把”迁移前、迁移后、回滚后”三个状态都留证据。
为这套迁移写一份验证清单,分三段。第一段迁移前:确认表结构基线、行数、索引现状的 SQL。第二段迁移后:确认字段类型、默认值、索引真的生效的 SQL,再加数据抽样,核对默认值是否覆盖了全部历史行。第三段回滚演练后:确认结构复原的 SQL。每条都要给可直接执行的 SQL,并注明期望结果是什么、不符合期望说明什么。
最后单独回答一个问题:这套迁移里你认为最可能在线上失败的一个点是什么,为什么。
预期产出:三段式验证 SQL 清单,每条附期望结果和异常解释。
第 5 步 · 在本地容器里演练两轮
正向跑一遍、回滚再跑一遍,两轮都过才算这套脚本可用。造数据的时候要盯着它别偷懒,channel_code 全是同一个值,验证就等于没做。
我要在本地 Docker 起的 MySQL 8.0 里把这次迁移演练一遍。给我一份演练顺序:1) 造测试数据的最小 SQL,t_order 和 t_user_profile 各一段,10 万行级别,channel_code 要有空值和至少三种取值,不要全是同一个默认值;2) 正向执行、验证、回滚、再验证这四步的终端命令顺序,一条一行;3) 每一步执行完我该看什么输出,看到什么才算这一步通过。
命令按 Linux 终端写,我用 Cursor 的终端直接跑。
预期产出:一套能在本地跑完的两轮演练命令,附每步通过标准。
实测记录
两个工具都在各自的免费额度内跑完,没有额外支出。下面是我这单的真实节奏,行数级别和上面需求原文一致。
| 环节 | 实际情况 |
|---|---|
| 整理需求到第一版方案 | 约 15 分钟,追问两次才把行数量级说清 |
| 生成正向与回滚脚本 | 约 10 分钟,两轮对话 |
| 本地演练正向加回滚各一遍 | 约 40 分钟,第二轮才全过 |
| 手工写同样两份脚本做对照 | 半天左右,还得找人帮忙看一眼 |
| 返工的地方 | 第一版漏了历史空值的回填顺序 |
最容易错的 3 个地方
- 先写正向再让 AI 补回滚,编号对不上还漏项。改:回滚先行。
- 加非空默认值列直接 ALTER,历史行被填了默认值。改:先可空后回填。
- 只演练正向不演练回滚,出事那天撤不回来。改:两轮都要跑。
第二条是我踩得最实的一次:业务上那批老订单根本没有渠道概念,填上 ‘web’ 之后报表口径直接错了,最后是补了一次数据订正才拉回来。
可复用的东西
这五段提示词其实是一套固定套路:结构化需求、回滚先行、正向对齐、三态验证、本地演练。换下一个变更,只需要改中间那段需求原文和行数量级。
我把它存成了一个模板,其它约束基本不用动。库名表名一律用化名,别把真实表结构直接贴进对话。这套流程跑顺之后,迁移脚本这件事就不再是上线前夜最慌的那一环了。
你手上最近一次表结构变更,回滚脚本是提前写好的,还是出问题那天现补的?
常见问题解答
AI 生成的迁移脚本能直接跑生产吗?
不能。它默认不知道你的真实行数、版本细节和索引现状。先在本地容器把正向和回滚各跑一遍,再按变更窗口分批执行。
为什么一定要先写回滚再写正向?
回滚是从目标态退回原态,先定好退路,正向脚本才有明确对照物。反过来写,回滚往往是倒着编的,容易漏项、编号也对不上。
表行数很大,AI 给的 ALTER 还能用吗?
要看它有没有显式给算法选项。MySQL 8.0 加列可走 INSTANT,改字段类型多为 COPY,几百万行以上建议错峰或用在线工具做,别只信默认脚本。
本网站的部分内容可能来源于网络或用户投稿,仅供大家学习与参考,如有侵权,请联系客服: hhxmw778 进行删除处理。
本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
教程如引导您添加微信或有另外收费服务,请自行甄别!
如遇充值环节或绑定支付账户或输入支付密码之类的异常步骤,建议停止操作!本站不对操作项目的损失负责!
本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现任何资源有问题请向站长举报下架
(手机微信用户建议用默认浏览器打开,可体验完整功能)
