No mysql 5.6 , considere estes 2 exemplos criando relacionamentos entre A, B, C e D.
Exemplo 1
CREATE TABLE `a` (
id INT UNSIGNED NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB;
CREATE TABLE `b` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE
) ENGINE = INNODB;
CREATE TABLE `c` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE
) ENGINE = INNODB;
CREATE TABLE `d` (
id INT UNSIGNED NOT NULL,
b INT UNSIGNED NOT NULL,
c INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES b (id) ON DELETE CASCADE,
FOREIGN KEY (id) REFERENCES c (id) ON DELETE RESTRICT
) ENGINE = INNODB;
INSERT INTO a VALUES (1);
INSERT INTO b VALUES (1, 1);
INSERT INTO c VALUES (1, 1);
INSERT INTO d VALUES (1, 1, 1);
DELETE FROM a;
O resultado é que todas as linhas são excluídas.
Exemplo 2
CREATE TABLE `a` (
id INT UNSIGNED NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB;
CREATE TABLE `b` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE
) ENGINE = INNODB;
CREATE TABLE `c` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE
) ENGINE = INNODB;
CREATE TABLE `d` (
id INT UNSIGNED NOT NULL,
b INT UNSIGNED NOT NULL,
c INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES b (id) ON DELETE RESTRICT,
FOREIGN KEY (id) REFERENCES c (id) ON DELETE CASCADE
) ENGINE = INNODB;
INSERT INTO a VALUES (1);
INSERT INTO b VALUES (1, 1);
INSERT INTO c VALUES (1, 1);
INSERT INTO d VALUES (1, 1, 1);
DELETE FROM a;
Observe que a única diferença é a mudança de qual chave estrangeira é RESTRICT de d . Este exemplo, no entanto, falha com
Código de erro: 1451 Não é possível excluir ou atualizar uma linha pai: uma restrição de chave estrangeira falha (
hello
.d
, CONSTRAINTd_ibfk_1
FOREIGN KEY (id
) REFERENCESb
(id
))
Embora logicamente, seja o mesmo que o Exemplo 1 . Sem ter olhado o código-fonte do MySQL , suspeito fortemente que as chaves estrangeiras são "aplicadas" em ordem lexical com base em seu nome. Qual será o comportamento padrão (ANSI-SQL) neste cenário?
Modifiquei o exemplo 1 para que a sintaxe seja aceita por todos os fornecedores que tentei. Acontece que o único DBMS dos testados que rejeita o cenário é o Db2 DB<>Fiddle :
Observe que as chaves estrangeiras precisam ser ligeiramente modificadas para Oracle e SQLServer. Veja os links fornecidos por Dinesh Kumar
Oracle SQL Server
Db2 lança uma exceção como:
SQL20255N FOREIGN KEY .. não é válido porque faria com que uma tabela descendente ... fosse conectada à exclusão à sua tabela ancestral ... por meio de vários relacionamentos com regras de exclusão conflitantes. O conflito é entre as regras de exclusão de restrições ... e ... na tabela descendente. Código do motivo = "3". SQLSTATE=42915 SQLCODE=-20255
Dei uma olhada no 7IWD2-02-Foundation-2011-12.pdf, que pode ser baixado em:
http://www.wiscorp.com/sql20nn.zip
mas não encontrei nada mencionado sobre isso.
Para mim, parece que o Db2 se comporta de maneira sã a esse respeito, mas essa é apenas a minha opinião.