简体   繁体   中英

How to design tables so delete queries on related tables will only remove relations between them?

I have teams and member tables which is joined by team_member table. teams and member have many to many relationship. When I delete team I need to remove all relation pairs (team - member) from team_member and according record from teams . I cannot set in team_member table ON DELETE CASCADE because it will delete member (who can be related to many teams). Same strategy goes for deleting member. What is the best way to design it?

Current design:

CREATE TABLE `member` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE `organization` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE `teams` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `rating` int(2) NOT NULL,
  `FK_Organization_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_Organization_id` (`FK_Organization_id`),
  CONSTRAINT `FK_Organization_id` FOREIGN KEY (`FK_Organization_id`) REFERENCES `organization` (`id`)
  ON CASCADE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

CREATE TABLE `team_member` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `FK_Member_id` int(11) NOT NULL,
  `FK_Team_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_Member_id` (`FK_Member_id`),
  KEY `FK_Team_id` (`FK_Team_id`),
  CONSTRAINT `FK_Member_id` FOREIGN KEY (`FK_Member_id`) REFERENCES `member` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_Team_id` FOREIGN KEY (`FK_Team_id`) REFERENCES `teams` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

I cannot set in team_member table ON DELETE CASCADE because it will delete member

ON DELETE CASCADE doesn't work like that. The following two foreign key constraints will

  • cascade deletes to team_member when a team is deleted, and
  • cascade deletes to team_member when a member is deleted.

In no case will deleting a team also delete rows from members, and in no case will deleting a member also delete rows from teams.

CONSTRAINT `FK_Member_id` FOREIGN KEY (`FK_Member_id`) 
  REFERENCES `member` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `FK_Team_id` FOREIGN KEY (`FK_Team_id`) 
  REFERENCES `teams` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION

Build the tables, add some rows, and test it yourself.

I think you can use a trigger :

delimiter $$
create trigger trig_remove_members_from_team
after delete on teams
for each row
begin
    delete from team_member where fk_team_id = OLD.id;
    -- You can perform additional insertions, updates or deletions
end $$
delimiter ;

This trigger will be executed just after you delete a row from teams .

Hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM