
使用 ChatGPT、Codex 修改数据库表关系时经常会遇到一种看起来“删除成功”实际上影响范围远超预期的问题明明只删了一条主记录结果关联表里的任务、附件、评论甚至历史记录也一起没了。常见表现包括删除一个项目下面的任务也全部消失删除一个订单关联明细一起被清掉接口返回200没有任何异常数据库也没有报错测试只验证“主记录删除成功”过一段时间才发现其他页面的数据也跟着少了。这类问题往往不是Delete语句写错了。而是外键上的级联删除规则已经替你继续往下删了。一、ON DELETE CASCADE到底做了什么假设有两张表project和task每个 task 都通过project_id关联 project。如果外键配置了ON DELETE CASCADE那么删除一条 project 时数据库会自动删除所有引用这条project的task。从数据库一致性的角度看这很方便。因为你不用手动一张张清理关联数据。但问题也正出在这里删除动作的真实影响范围变大了。二、为什么接口看起来完全正常因为数据库认为整个操作是合法的。例如接口执行删除项目ID1001主表删除成功。关联任务也根据外键规则自动删除。事务正常提交。最后返回200 OK整个过程中可能没有任何异常。所以单纯看接口状态码你根本发现不了到底顺带删掉了多少数据。三、最危险的是“多层级联”比如关系是项目 → 任务 → 评论 → 附件如果每一层都配置了级联删除那么删除项目时影响链可能变成1条项目→20条任务→300条评论→500个附件记录最终一个简单Delete可能影响几百条数据。这就是为什么级联删除最需要关注的不是能不能删成功。而是会沿着关系链继续删到哪里。四、Codex为什么容易顺手加上CASCADE因为从代码实现角度看CASCADE确实很“干净”。没有它时删除主记录可能报foreign key constraint failed于是 Codex 很容易得出一个直接解决方案给外键加ON DELETE CASCADE。这样错误马上消失。但这里真正应该先问的是这些子数据是不是业务上也应该被一起删除数据库约束正确不等于业务规则正确。五、有些关联数据其实应该保留例如删除一个项目以后任务可以删除。但审计记录可能必须保留。又比如删除用户以后用户资料可以失效。但历史订单、财务记录通常不能因为用户删除就一起消失。所以关联关系不能简单理解成有父子关系就应该CASCADE。更合理的判断应该是生命周期是不是完全一致。只有真正“随父记录一起出生、一起消失”的数据才更适合考虑级联删除。六、CASCADE、RESTRICT和SET NULL不是一回事数据库常见的删除策略不只有CASCADE。CASCADE父记录删除子记录一起删除。RESTRICT / NO ACTION存在关联数据时不允许直接删除父记录。SET NULL父记录删除后子记录保留但关联字段变成NULL。到底选哪一种取决于业务关系。如果关联数据价值很高很多时候阻止删除反而比自动删除更安全。七、软删除和物理删除也要分清有些项目已经采用deleted_at或者is_deleted做软删除。这时候如果某一层突然用了数据库CASCADE物理删除就可能出现很奇怪的结果主记录只是被标记删除。但关联数据却真的被物理清掉。或者反过来主记录物理删除后历史数据全部跟着消失。所以在已有软删除体系里更要明确哪些表允许物理删除哪些必须保留历史。八、测试不能只检查“主记录没了”例如测试代码只验证删除后查询不到project。这个测试即使通过也不代表删除行为正确。更完整的测试应该继续检查task还在不在comment是否应该保留attachment是否被误删audit log是否还存在关联数量是否符合预期。真正该验证的是删除后的整个数据状态。九、删除前最好先做影响范围检查对于高风险删除操作可以先统计这条主记录当前关联多少子数据例如删除前先确认12个任务46条评论8个附件3条历史记录。这样才能知道这次删除到底会影响多少数据。如果实际影响范围明显超过预期就应该先停下来。不要让Agent看到外键报错以后就自动把CASCADE一路加下去。十、可以直接这样让ChatGPT、Codex检查以后让 ChatGPT、Codex 修改数据库删除逻辑可以直接要求如果删除主记录遇到外键约束不要直接默认增加ON DELETE CASCADE。先列出所有关联表和依赖关系确认每类数据的生命周期是否应该随主记录一起结束。分别评估CASCADE、RESTRICT、SET NULL和软删除并检查是否存在多层级联。修改完成后不只验证主记录被删除还要验证每张关联表最终应该保留还是删除。这样能避免把“解决外键报错”变成“把一串历史数据一起删掉”。最后Codex加了级联删除以后删一条主记录关联数据也跟着没了真正的问题通常不是数据库执行错了。恰恰相反。数据库只是严格执行了你定义好的删除规则。真正应该关注的是这条规则是否符合业务数据的生命周期。所以删除逻辑设计时最好始终检查关联关系 → 生命周期 → 删除策略 → 多层影响 → 最终数据状态。以后看到删除接口成功了。不要只确认主记录不存在。还要再问一句它到底顺带删掉了什么持续更新 ChatGPT、Codex、AI编程与后端工程实战内容更多深度内容和稳定订阅渠道欢迎搜索关注「孤狼GPT」。