删表前的检查清单
删表是不可逆操作,恢复成本取决于备份的时效与完整度。执行前要确认三件事:有没有别的表通过外键引用它、有没有视图或依赖对象建立在它之上、最近一次备份能不能恢复到删表前的时点。两种数据库对依赖的处理方式不同:MySQL 在存在外键引用时直接拒绝删除,PostgreSQL 默认也拒绝,但如果顺手加了级联关键字,依赖对象会被静默一起删掉。
基本信息
| 适用平台 | MySQL 8.0 / PostgreSQL 12 及以上 |
|---|---|
| MySQL 默认行为 | 存在外键引用时删除失败 |
| PostgreSQL 默认行为 | 存在依赖对象时拒绝删除,除非显式要求级联 |
| 常见的温和做法 | 先把表改名并观察一段时间,确认无人使用后再删除 |
| 权限建议 | 生产环境不向日常账号开放删表权限,走审批流程 |
典型使用场景
- 下线废弃业务:确认无引用后清理历史表
- 重构替换:新表上线稳定后再删旧表
- 数据归档收尾:确认归档数据已落地并校验过条数
- 清理测试期间临时创建的表
- 排查误删:先查清依赖关系,再评估恢复路径
先查引用与依赖
先查引用与依赖
-- MySQL:查询哪些表的外键指向目标表
SELECT table_name, constraint_name
FROM information_schema.KEY_COLUMN_USAGE
WHERE referenced_table_name = 'orders';
-- MySQL:先改名观察,确认无人使用后再删除
RENAME TABLE orders TO orders_deprecated_2026;
-- 观察一到两周,确认没有报错与依赖后:
-- DROP TABLE orders_deprecated_2026;
-- PostgreSQL:用系统目录查看依赖对象(视图、约束等)
SELECT dependent_ns.nspname AS schema_name,
dependent_view.relname AS dependent_object
FROM pg_depend
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid
JOIN pg_class AS dependent_view ON pg_rewrite.ev_class = dependent_view.oid
WHERE pg_depend.refobjid = 'orders'::regclass;
-- 备份确认:删除前先确认最近一次备份可恢复到当前时点依赖处理对照
| 情况 | MySQL 行为 | PostgreSQL 行为 |
|---|---|---|
| 其他表通过外键引用 | 删除失败并报错 | 删除失败并报错 |
| 存在视图或依赖对象 | 允许删除,视图后续报错 | 默认拒绝,需显式级联 |
| 强制级联删除 | 需先关闭外键检查 | 加级联关键字后依赖对象一起删 |
| 恢复难度 | 依赖备份时效 | 依赖备份时效 |
在 PostgreSQL 里用级联关键字删表,依赖的视图、约束会被一并删除,而且这些对象往往不在本次变更的评审范围内。删表前把依赖对象查出来逐个确认,比事后重建便宜得多。
关闭外键检查来绕过删除限制会留下悬空引用:子表里指向已删父表的记录从此无法通过约束校验,后续的关联查询会出现无法解释的空结果。这种状态下运维,比当场报错麻烦得多。