PostgreSQL 中的外键 ON DELETE CASCADE

Bilal Shahid 2022年5月14日
PostgreSQL 中的外键 ON DELETE CASCADE

在我们开始研究在 PostgreSQL 中实现 ON DELETE CASCADE 的不同解决方案之前,我们将首先了解 ON DELETE CASCADE 的含义以及它的作用。

让我们假设你有两个表,其中一个从父表继承一个 KEY 并使用它的值,也称为 ASSOCIATION。现在假设用户想要删除父表中的这一行。

可是等等?子表中继承的行会发生什么?

你可能会认为此 VIOLATION 会引发错误。正确的!幸运的是,这不起作用,并且会产生错误。

ERROR:  update or delete on table [your_table] violates foreign key constraint [f_key] on table [your_table]

但是,如果你不想限制 DELETE,而是继续从两个表中 DELETE 这一行,该怎么办。这就是我们的操作所在。

让我们看看它是如何工作的。

在 PostgreSQL 中使用 ON DELETE CASCADE

让我们首先创建一个 Vehicle 表。

create table vehicle (
	id int PRIMARY KEY,
	OWNER TEXT
);

现在让我们定义另一个名为 BUS 的表,它将从 VEHICLE 继承键 ID

create table bus (
	id int PRIMARY KEY references vehicle,
	Model TEXT
);

你可以在 ID 定义的末尾看到 REFERENCES 标签。这意味着它现在引用 VEHICLE 表中的行,并且该表中的任何 IDVEHICLE 表中的 ID 不匹配的 INSERT 操作将被拒绝。

现在让我们假设我们在 VEHICLE 表中 INSERT 了一些值。

Insert into vehicle values (1, 'mark'), (2, 'john');

让我们也 INSERT 一个值到 BUS 表中。

insert into bus values (2, 'High_Van');

所以现在 BUS 表指的是 VEHICLE 表中的 KEY``2,这意味着 High_Van 属于 John

现在让我们尝试从 BUS 中删除该条目。

如果你打电话:

delete from vehicle where id = 2

将返回一个错误。

ERROR:  update or delete on table "vehicle" violates foreign key constraint "bus_id_fkey" on table "bus"
DETAIL:  Key (id)=(2) is still referenced from table "bus".

这告诉你在表 BUS 中仍然引用 KEY``2。因此 DELETE 将不起作用。现在让我们定义如果我们调用 DELETE 会发生什么。

BUS 表中,修改 ID 列。

create table bus (
	id int PRIMARY KEY references vehicle ON DELETE CASCADE,
	Model TEXT
);

现在,当我们尝试 DELETE 时,它可以完美运行。为什么?因为 CASCADE 倾向于删除子表中为 DELETE 建议的行。

假设你最好使用原始方法并想要定义你的方法。在这种情况下,你可以尝试将 ON DELETE CASCADE 更改为 ON DELETE RESTRICT,这最终将限制任何发生冲突的 DELETE 操作。

你甚至可以通过其他方式将这些选项用于 ON UPDATE 操作。

在 PostgreSQL 中关于定义多个 ON CASCADE DELETE 约束所面临的问题的简短说明

当你删除引用数千个表的行时,对所有继承表进行 ON DELETE CASCADE 会产生问题。这将产生一个问题,但回滚到任何更改都极不可能。

始终确保对 DELETE 使用良好的做法。如果你想 CASCADE,请调用 DELETE 的函数,然后进行 TRANSACTION 并不断检查是否发生错误而不是在最后。

这将保证你的数据库的安全性和安全性,并避免将来出现问题。

我们希望你学会了如何在 PostgreSQL 中执行 ON DELETE CASCADE 操作。

作者: Bilal Shahid
Bilal Shahid avatar Bilal Shahid avatar

Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!

GitHub