我如何使用 MySQL 的递归关系进行 CASCADE ON DELETE

How can I CASCADE ON DELETE with a Recursive Relationships with MySQL

我有这个代码:

CREATE TABLE Employee (idEmployee int PRIMARY KEY, nane varchar(100));
CREATE TABLE Friend (idFriendA integer, idFriendB integer, 
                     FOREIGN KEY (idFriendA) REFERENCES Employee (idEmployee) ON DELETE CASCADE, 
                     FOREIGN KEY (idFriendB) REFERENCES Employee (idEmployee) ON DELETE CASCADE);
INSERT INTO Employee (idEmployee, nane) VALUES (0, 'Bob'),(1, 'Jean');
INSERT INTO Friend (idFriendA, idFriendB) VALUES (0, 1);

而且我希望如果我删除 Employee 中的 id 0,它会使用关系 Friend 级联删除 Employee 中的 id 1。

我试过为 idFriendB 添加主键,但没有成功

另一种解决方案是触发器,但如果我们尝试更改触发器中的 table 以在同一个 table 上删除,我们会收到 table 正在变异的所有错误。
另一种方法是删除 Friends 中的条目并使用触发器删除 Employees 中的 2 行。
注意我不确定逻辑是什么。如果其中一名员工有另一个朋友会怎样?我们是否级联更多删除?看看 Bill 的例子,当她失去朋友 Bob 时,Bill 突然失去了他的朋友 Jean。我们在哪里停下来?员工可以没有朋友吗?

CREATE TABLE Employee (
idEmployee int PRIMARY KEY, 
nane varchar(100));
CREATE TABLE Friend (
idFriendA integer, 
idFriendB integer, 
FOREIGN KEY (idFriendA) 
REFERENCES Employee (idEmployee) 
ON DELETE CASCADE, 
FOREIGN KEY (idFriendB) 
REFERENCES Employee (idEmployee) 
ON DELETE CASCADE);
INSERT INTO Employee 
(idEmployee, nane) VALUES 
(0, 'Bob'),
(1, 'Jean'),
(2,'Bill');
INSERT INTO Friend 
(idFriendA, idFriendB) VALUES
 (0, 1),
 (1, 2);
✓

✓

✓

✓
create trigger deleteFriend
before delete on Friend
for each row
delete from Employee
where idEmployee = old.idFriendA 
or idEmployee = old.idFriendB;
select * from Friend;
select * from Employee;
idFriendA | idFriendB
--------: | --------:
        0 |         1
        1 |         2

idEmployee | nane
---------: | :---
         0 | Bob 
         1 | Jean
         2 | Bill
delete from Friend where idFriendA = 0
select * from Friend;
select * from Employee;
idFriendA | idFriendB
--------: | --------:

idEmployee | nane
---------: | :---
         2 | Bill

db<>fiddle here

根据说明我建议最好只用一个table。我们使用递归外键来确保父项存在。 (我们为文件系统 Id 1 的根例外,它是 /

CREATE TABLE Files (
fileId integer PRIMARY KEY, 
name varchar(100) NOT NULL,
parentId integer, 
FOREIGN KEY (parentId) 
REFERENCES Files (fileId) 
ON DELETE CASCADE, 
CONSTRAINT Parent_Not_Self CHECK 
(parentId <>  fileId OR fileId = 1));
INSERT INTO Files VALUES
(1,'/',1);
INSERT INTO Files VALUES
(2,'/ twin',2);
Check constraint 'Parent_Not_Self' is violated.
INSERT INTO Files VALUES
(3,'alone',4);
Cannot add or update a child row: a foreign key constraint fails (`db_1032216260`.`Files`, CONSTRAINT `Files_ibfk_1` FOREIGN KEY (`parentId`) REFERENCES `Files` (`fileId`) ON DELETE CASCADE)
INSERT INTO Files VALUES
(2,'/etc',1),
(3,'/home',1),
(4,'/mnt',1),
(5,'/home/user_name',3);
SELECT * FROM Files p
JOIN Files c
ON c.parentId = p.fileId;
fileId | name  | parentId | fileId | name            | parentId
-----: | :---- | -------: | -----: | :-------------- | -------:
     1 | /     |        1 |      1 | /               |        1
     1 | /     |        1 |      2 | /etc            |        1
     1 | /     |        1 |      3 | /home           |        1
     1 | /     |        1 |      4 | /mnt            |        1
     3 | /home |        1 |      5 | /home/user_name |        3

db<>fiddle here