SQL删除数据时存在依赖关系_设置外键级联删除ON DELETE

外键未设ON DELETE CASCADE导致删主表报错,因默认RESTRICT阻止操作;应建表时定义级联,已有表需先查外键名再重建;级联会递归删除整条依赖链,执行前须逐层SELECT确认影响范围。外键没加 ON DELETE CASCADE,删主表就报错MySQL 或 PostgreSQL 里删父记录时提示 Cannot delete or update a parent row: a foreign key constraint fails,基本就是子表外键没配级联行为。默认是 RESTRICT(或 NO ACTION),数据库直接拦住操作,不给你删。实操建议:建表时就写明:在子表外键定义里加上 ON DELETE CASCADE,比如 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE已有表要补加?MySQL 不支持直接 ALTER TABLE ... ADD FOREIGN KEY ... ON DELETE CASCADE,得先 DROP 原外键(得知道它的名字,查 SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME='xxx' AND COLUMN_NAME='xxx'),再重建PostgreSQL 稍友好些,可用 ALTER TABLE child_table DROP CONSTRAINT fk_name; ALTER TABLE child_table ADD FOREIGN KEY (col) REFERENCES parent(col) ON DELETE CASCADE;级联删除会一并删掉多少行?怎么提前确认ON DELETE CASCADE 不是"删一行、带出一行",而是递归清理整条依赖链------只要外键路径存在,就会一路删下去。比如 orders → order_items → inventory_logs,删一个订单,可能连带删几十条日志。实操建议:执行前务必用 SELECT 模拟影响范围:比如想删 users 表中 id=123 的用户,先查 SELECT COUNT(*) FROM orders WHERE user_id = 123,再查 SELECT COUNT(*) FROM order_items WHERE order_id IN (SELECT id FROM orders WHERE user_id = 123),逐层摸清规模别依赖 ORM 的软删逻辑------如果 ORM 层做了 before_destroy 钩子,但数据库外键又开了 CASCADE,可能重复删或冲突MySQL 8.0+ 支持 FOREIGN_KEY_CHECKS = 0 临时关检查,但这是绕过约束,不是替代级联;关了之后删数据不会触发级联,子表残留孤儿记录PostgreSQL 和 MySQL 的 ON DELETE 行为差异语法看着一样,但底层处理和默认值有坑。MySQL 默认是 RESTRICT,PostgreSQL 默认也是 RESTRICT,但 MySQL 的 CASCADE 不支持跨 schema 级联(除非同库同 schema),而 PostgreSQL 在同一数据库内支持跨 schema 外键(需显式指定 schema 名)。 Shakespeare 一款人工智能文案软件,能够创建几乎任何类型的文案。

相关推荐
kobe_OKOK_3 小时前
DRF接口幂等操作
python·django
廿士3 小时前
python脚本使用相关
python
正儿八经的少年3 小时前
布隆过滤器(解决redis缓存穿透步骤之一)
数据库·redis·缓存
青 春 记 忆3 小时前
零基础入门python19:Flask账本第一步——应用工厂、蓝图和健康检查
python·flask·后端开发
朦胧之3 小时前
Python 后端核心知识
python
xrandzj4 小时前
MySQL8.0 从零通关核心操作手册(Ubuntu实战版)
数据库·mysql
我不会插花弄玉4 小时前
4.数据类型【由浅入深-MySQL】
数据库·mysql
denggun123454 小时前
yield
前端·数据库·python
ltl4 小时前
SQLite Rollback Journal:写前拷贝与提交点
数据库
ltl4 小时前
TiFlash Learner:Raft 日志如何进列存
数据库