多对多关系——自动删除孤儿
Many-to-many relation - automatically delete orphans
假设球队和球员之间存在多对多关系。这是由下表建模的:
create table team
(
identifier integer primary key
);
create table player
(
identifier integer primary key
);
create table member
(
team_identifier integer,
player_identifier integer,
primary key(team_identifier, player_identifier),
foreign key(team_identifier) references team on update cascade on delete cascade,
foreign key(player_identifier) references player on update cascade on delete cascade
);
假设以下数据:
insert into team values(1);
insert into team values(2);
insert into player values(1);
insert into member values(1, 1);
insert into member values(2, 1);
让我们删除团队:
delete from team where identifier = 1;
delete from team where identifier = 2;
现在我们有一个没有团队的球员。有没有办法自动删除这个播放器?也就是说,当删除一个团队导致一个孤儿玩家时,这个玩家也应该被删除(而不是相反)。
嗯,不一定。如果您计划稍后将他添加到团队中,该玩家仍然可以被视为需要团队的玩家。或者,如果您想要拉动可用的玩家。
不过,您可以尝试使用
DELETE FROM member WHERE team_identifier = 1
DELETE FROM member WHERE team_identifier = 2
DELETE FROM player
WHERE Identifier NOT IN (SELECT player_identifier FROM member)
解决您问题的理想方案
在成员中创建删除后触发器或更新:
CREATE FUNCTION delete_player_not_in_member() RETURNS trigger AS $delete_player_not_in_member$
BEGIN
DELETE FROM player WHERE Identifier NOT IN (SELECT player_identifier FROM membre);
RETURN OLD;
END;
$delete_player_not_in_member$ LANGUAGE plpgsql;
CREATE TRIGGER delete_player_not_in_member AFTER DELETE OR UPDATE ON member
FOR EACH ROW EXECUTE PROCEDURE delete_player_not_in_member();
最简单的是添加一个跟踪团队删除的触发器,如下所示:
CREATE TRIGGER drop_orphan_player
AFTER DELETE ON team FOR EACH ROW
DELETE FROM player
WHERE id NOT IN (
SELECT DISTINCT player_id FROM member
);
查看它在 SQLfiddle 的工作情况。
假设球队和球员之间存在多对多关系。这是由下表建模的:
create table team
(
identifier integer primary key
);
create table player
(
identifier integer primary key
);
create table member
(
team_identifier integer,
player_identifier integer,
primary key(team_identifier, player_identifier),
foreign key(team_identifier) references team on update cascade on delete cascade,
foreign key(player_identifier) references player on update cascade on delete cascade
);
假设以下数据:
insert into team values(1);
insert into team values(2);
insert into player values(1);
insert into member values(1, 1);
insert into member values(2, 1);
让我们删除团队:
delete from team where identifier = 1;
delete from team where identifier = 2;
现在我们有一个没有团队的球员。有没有办法自动删除这个播放器?也就是说,当删除一个团队导致一个孤儿玩家时,这个玩家也应该被删除(而不是相反)。
嗯,不一定。如果您计划稍后将他添加到团队中,该玩家仍然可以被视为需要团队的玩家。或者,如果您想要拉动可用的玩家。
不过,您可以尝试使用
DELETE FROM member WHERE team_identifier = 1
DELETE FROM member WHERE team_identifier = 2
DELETE FROM player
WHERE Identifier NOT IN (SELECT player_identifier FROM member)
解决您问题的理想方案 在成员中创建删除后触发器或更新:
CREATE FUNCTION delete_player_not_in_member() RETURNS trigger AS $delete_player_not_in_member$
BEGIN
DELETE FROM player WHERE Identifier NOT IN (SELECT player_identifier FROM membre);
RETURN OLD;
END;
$delete_player_not_in_member$ LANGUAGE plpgsql;
CREATE TRIGGER delete_player_not_in_member AFTER DELETE OR UPDATE ON member
FOR EACH ROW EXECUTE PROCEDURE delete_player_not_in_member();
最简单的是添加一个跟踪团队删除的触发器,如下所示:
CREATE TRIGGER drop_orphan_player
AFTER DELETE ON team FOR EACH ROW
DELETE FROM player
WHERE id NOT IN (
SELECT DISTINCT player_id FROM member
);
查看它在 SQLfiddle 的工作情况。