删除具有递归外键约束的记录

时间:2018-12-30 19:16:02

标签: mysql foreign-keys constraints

从具有外键到另一个表而另一个表具有外键的表中删除记录的最佳方法是什么?

例如,我有下表。 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上将CASCADE DELETE删除到帐户,我还是试图显式删除网络,以期解决外键约束,但是并没有成功。

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;

1 个答案:

答案 0 :(得分:0)

两个表之间都具有约束相互依赖性。这不是一个好的设计,因为它会使DDL和DML操作变得比通常所需的更为复杂。

除了临时禁用外键外,执行成功的DELETE的唯一可能解决方案是使引用字段之一为可空,以便在删除之前将其设置为NULL即可破坏该关系。 ON DELETE CASCADE将负责将相关记录删除到另一个表中。

使引用字段之一为可空:

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.