pg on delete 策略探讨

你好!很高兴能和你探讨 PostgreSQL(以下简称 PG)的知识。

作为一名资深开发者,你一定处理过不少"脏数据"或者"孤儿数据"。在数据库的世界里,当我们删除一条记录时,那些引用它的"下游数据"该何去何从?这就是 ON DELETE 策略要解决的核心问题:如何维护参照完整性(Referential Integrity)。

🌱 本节目标

理解 PG 中外键删除(ON DELETE)的五种处理方式,并建立一套"场景驱动"的选择逻辑。


🧠 核心概念

  1. 父表 (Parent Table) :被引用的表(如:用户表 users)。
  2. 子表 (Child Table) :持有外键的表(如:订单表 orders,通过 user_id 引用用户)。
  3. 副作用 (Side Effects):当你删掉"父"时,"子"应该报错、跟着消失、还是原地待命?

❓ 苏格拉底式引导问题

在深入语法前,请先调动你的架构师直觉思考以下场景:

  1. 如果你在做一个 留学中介系统,删除了一个"国家"(如:英国),那么关联这个国家的所有"学校"数据应该被自动删掉吗?还是应该提示报错?
  2. 如果你在做 SEO 流量统计,删除了一个"域名",那些关联该域名的"每日访问日志"还有留着的必要吗?
  3. 在 Rust 或 Go 中,如果你释放了一个父对象的内存,但子对象还持有一个失效的指针,会发生什么?数据库的 ON DELETE 是否就是在处理这种"野指针"问题?

🧩 策略拆解与类比

PG 提供了五种主要的策略。我们可以用**"文件系统操作""代码逻辑"**来类比:

策略 (Strategy) 中文释义 程序员视角类比 行为描述
NO ACTION 不采取行动 编译器报错 默认选项。如果还有子记录,直接报错。但在事务结束时才最终检查。
RESTRICT 限制/禁止 Runtime Panic 立即报错。只要发现有子记录关联,不允许删除父记录。
CASCADE 级联 rm -rf 连坐。父记录没了,子记录也自动被删除。
SET NULL 设为空 指针置为 nil 断开联系。父记录删除,子记录的相关字段设为 NULL
SET DEFAULT 设为默认 重置为默认配置 改嫁。父记录删除,子记录的相关字段恢复到定义的 DEFAULT 值。
1. 强一致性防御:RESTRICT / NO ACTION

这是最保守的策略。

  • 场景:银行账户与交易记录。你不能直接删掉一个还有流水记录的账户。
  • 直觉"只要有人还在引用我,我就不准消失。"
2. 自动化清理:CASCADE
  • 场景 :SEO 系统中,删除一个 Task(任务),那么该任务抓取到的 RawData(原始数据)通常也没用了。
  • 直觉"父亡子随,干净利落。"
3. 历史留存:SET NULL
  • 场景 :留学中介系统中,删除了一个 Consultant(顾问),但该顾问签约的 Student(学生)记录必须保留,只是"所属顾问"这一栏变空。
  • 直觉"人走了,事还得留着,只是暂时没负责人。"

📊 决策矩阵(程序员速查)

如果你不确定选哪个,看这张表:
必须保留
不需要,随父去
暂时断开关系
强制要求先处理子项
转移到默认值
准备删除父记录
子记录必须保留吗?
子记录需要关联吗?
CASCADE 级联删除
SET NULL 设为空
RESTRICT 报错禁止
SET DEFAULT 设为默认


✅ 小结

  • 默认 (Default) :如果不写,PG 默认是 NO ACTION
  • 最常用CASCADE(用于日志/临时数据)和 RESTRICT(用于核心业务资产)。
  • 最安全SET NULL(适合 2B 业务中需要审计和保留历史的场景)。
  • 注意点CASCADE 虽然爽,但在超大数据量下会导致长时间锁表,慎用。

相关推荐
Bioinfo Guy1 小时前
高分Panel复现系列|转录因子网络太乱?用模块框把重点圈出来
数据库·生物信息学·生信可视化
ltl2 小时前
Disaggregated DB 合集:Socrates、PolarDB、Taurus 的共同模式
数据库
Blossom i4 小时前
大数据预处理与采集实验一:使用Python操作MySQL数据库
数据库·mysql
雾时之林5 小时前
Linux--软件管理、源码包安装
linux·服务器·数据库
老纪的技术唠嗑局7 小时前
超级干货分享:中小企业使用 OceanBase 实践经验汇总
数据库
CLOUD ACE7 小时前
谷歌云代理|零售商Target 如何利用 Spanner Graph 提升零售发现体验并将数据库维护成本降低 50%
数据库·零售
AI大模型-小雄7 小时前
Codex写分页接口为什么越翻越慢?用Cursor Pagination解决重复与漏数据
大数据·数据库·elasticsearch·搜索引擎·chatgpt·后端开发·codex
少晓年8 小时前
从 MySQL 迁移到人大金仓 KingbaseES:完整指南与实践
数据库·mysql
SelectDB9 小时前
Apache Doris AI RAG 实战:从基础 RAG 到知识图谱增强的技术能力与选型
数据库
SelectDB9 小时前
电商企业 PostgreSQL 迁移 Apache Doris:80TB 分析数据统一平台技术能力与实践
数据库