Eu tenho duas tabelas em MySQL database- parent
, child
. Estou tentando adicionar referências de chave estrangeira à minha tabela filho com base na tabela pai. Existe alguma diferença significativa entre ON UPDATE CASCADE
eON DELETE CASCADE
My Parent Table
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
Minha pergunta é: Qual é a diferença entre as seguintes consultas sql.
ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=INNODB;
Há algum erro nas consultas? O que essas consultas (1,2 e 3) significam? Eles são iguais ???
mysql
innodb
mysql-5.5
foreign-key
Lobo solitário
fonte
fonte
Respostas:
Um tópico muito bom sobre esse assunto pode ser encontrado aqui e também aqui . O guia definitivo para o MySQL é, obviamente, a documentação, encontrada aqui .
No padrão SQL 2003, existem 5 ações referenciais diferentes:
Para responder à pergunta:
CASCATA
ON DELETE CASCADE
significa que, se o registro pai for excluído, qualquer registro filho também será excluído. Esta não é uma boa ideia na minha opinião. Você deve acompanhar todos os dados que já estiveram em um banco de dados, embora isso possa ser feito usandoTRIGGER
s. (No entanto, veja ressalva nos comentários abaixo).ON UPDATE CASCADE
significa que, se a chave primária pai for alterada, o valor filho também será alterado para refletir isso. Novamente, na minha opinião, não é uma ótima idéia. Se você está mudandoPRIMARY KEY
s com alguma regularidade (ou mesmo!), Há algo errado com seu design. Mais uma vez, veja os comentários.ON UPDATE CASCADE ON DELETE CASCADE
significa que, se vocêUPDATE
OUDELETE
o pai, a alteração é transmitida em cascata ao filho. Isso é o equivalenteAND
aos resultados das duas primeiras declarações.RESTRINGIR
RESTRICT
significa que qualquer tentativa de excluir e / ou atualizar o pai falhará ao gerar um erro. Esse é o comportamento padrão no caso de uma ação referencial não ser especificada explicitamente.SEM AÇÃO
NO ACTION
: A partir do manual do . Uma palavra-chave do SQL padrão. No MySQL, equivalente aRESTRICT
. O MySQL Server rejeita a operação de exclusão ou atualização da tabela pai se houver um valor de chave estrangeira relacionado na tabela referenciada. Alguns sistemas de banco de dados possuem verificações adiadas eNO ACTION
é uma verificação adiada. No MySQL, restrições de chave estrangeira são verificadas imediatamente,NO ACTION
o mesmo acontece comRESTRICT
.SET NULL
SET NULL
- novamente a partir do manual. Exclua ou atualize a linha da tabela pai e defina a coluna ou colunas da chave estrangeira na tabela filho comoNULL
. Esta não é a melhor das idéias IMHO, principalmente porque não há como "viajar no tempo" - ou seja, olhar de volta para as tabelas filho e associar registros comNULL
s ao registro pai relevante -CASCADE
ou useTRIGGER
s para preencher as tabelas de log para rastrear mudanças (mas, veja comentários).CONJUNTO PADRÃO
SET DEFAULT
. Mais uma parte (potencialmente muito útil) do padrão SQL que o MySQL não se deu ao trabalho de implementar! Permite que o desenvolvedor especifique um valor para o qual definir a (s) coluna (s) de chave estrangeira em um UPDATE ou DELETE. O InnoDB e o NDB rejeitarão as definições da tabela com umaSET DEFAULT
cláusula.Como mencionado acima, você deve passar algum tempo olhando a documentação aqui .
fonte
Essas duas são ações a serem executadas, respectivamente, quando o registro referenciado na tabela pai altera seu ID e quando é excluído.
Se você executar:
E há pelo menos um registro
child
comparent_id = 1
, 1) falhará; nos casos 2) e 3), todos os registros com parent_id = 1 são atualizados para parent_id = -1.Se você executar:
E há pelo menos um registro
child
comparent_id = 1
, 2) falhará; nos casos 1) e 3), todos os registros comparent_id = 1
são excluídos.3) está sintaticamente correto.
A documentação completa pode ser encontrada no manual .
fonte
Não tenho reputação suficiente para comentar as respostas anteriores. Então pensei em elaborar um pouco.
1) EM EXCLUIR CASCADE significa que, se o registro pai for excluído, qualquer registro filho de referência também será excluído. O padrão ON UPDATE é RESTRICT, o que significa que a atualização no registro pai falhará.
2) A ação ON DELETE assume como padrão RESTRICT, o que significa que DELETE no registro pai falhará. ON UPDATE O CASCADE atualizará todos os registros filhos de referência quando o registro pai for atualizado.
3) Veja as ações CASCADE em 1) e 2) acima.
Ao usar IDs de registro pai como chaves estrangeiras (em tabelas filho) - a experiência diz que a) se os IDs são números de sequência gerados automaticamente, NÃO os use como chaves estrangeiras. Use outra chave pai exclusiva. b) se os IDs são GUIDs, não há problema em usá-los como chaves estrangeiras. Você verá a sabedoria desta sugestão ao exportar e importar os registros ou copiá-los para outro banco de dados. É muito complicado lidar com números de sequência gerados automaticamente durante a migração de dados quando eles são referenciados como chaves estrangeiras.
fonte