使用递归外键约束删除记录

dsekswqp  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(330)

如果一个表的外键指向另一个表,而另一个表的外键指向另一个表,那么从该表中删除记录的最佳方法是什么?
例如,我有以下表格。 accounts 有一个或多个网络和 accounts 必须有一个默认网络。

CREATE TABLE IF NOT EXISTS accounts (
  id INT NOT NULL,
  networksId INT NOT NULL,
  PRIMARY KEY (id),
  INDEX fk_accounts_networks1_idx (networksId ASC),
  CONSTRAINT fk_accounts_networks1
    FOREIGN KEY (networksId)
    REFERENCES networks (id)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS networks (
  id INT NOT NULL AUTO_INCREMENT,
  accountsId INT NOT NULL,
  PRIMARY KEY (id),
  INDEX fk_sites_accounts1_idx (accountsId ASC),
  CONSTRAINT fk_sites_accounts1
    FOREIGN KEY (accountsId)
    REFERENCES accounts (id)
    ON DELETE CASCADE
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

即使我有一个级联删除网络fk到帐户,我试图明确删除网络,希望绕过外键约束,但是,没有成功。

DELETE a, n FROM accounts a INNER JOIN networks n ON n.accountsId=a.id WHERE a.id=123;

我唯一的解决办法是这样的吗?

SET FOREIGN_KEY_CHECKS=0;
DELETE FROM networks WHERE accountsId=123;
SET FOREIGN_KEY_CHECKS=1;
DELETE FROM accounts WHERE id=123;
2vuwiymt

2vuwiymt1#

两个表之间有一个约束相互依赖关系。这不是一个好的设计,因为它往往使ddl和dml操作比通常需要的更复杂。
除了暂时禁用外键之外,执行成功删除的唯一可能的解决方案是使其中一个引用字段可以为null,这样您就可以在删除前将其设置为null来中断关系。on delete级联将负责删除另一个表中的相关记录。
使引用字段之一为空:

ALTER TABLE networks MODIFY accountsId INT NULL;

删除:

UPDATE network SET accountsId = NULL WHERE id = ?;
DELETE FROM network WHERE id = ?;
-- the corresponding record in table accounts gets automatically deleted.

相关问题