Não crio esquemas todos os dias, mas quando faço isso, tento configurar atualizações/exclusões em cascata corretamente para facilitar a administração. Eu entendo como as cascatas funcionam, mas nunca consigo lembrar qual tabela é qual.
Por exemplo, se eu tiver duas tabelas - Parent
e Child
- com uma chave estrangeira nessas Child
referências Parent
e tiver ON DELETE CASCADE
, quais registros acionam uma cascata e quais registros são excluídos pela cascata? Meu primeiro palpite seria que os Child
registros são excluídos quando Parent
os registros são excluídos, já que Child
os registros dependem dos Parent
registros, mas o ON DELETE
é ambíguo; pode significar excluir o Parent
registro quando o Child
registro for excluído ou pode significar excluir o Child
registro quando o Parent
for excluído. Então qual é?
Eu gostaria que a sintaxe fosse ON PARENT DELETE, CASCADE
, ON FOREIGN DELETE, CASCADE
ou algo semelhante para remover a ambiguidade. Alguém tem algum mnemônico para lembrar disso?
Se você gosta dos termos
Parent
eChild
e acha que eles são fáceis de serem lembrados, você pode gostar da tradução deON DELETE CASCADE
paraLeave No Orphans!
O que significa que quando uma
Parent
linha é excluída (eliminada), nenhuma linha órfã deve permanecer ativa naChild
tabela. Todos os filhos da linha pai também são eliminados (excluídos). Se algum desses filhos tiver netos (em outra tabela por meio de outra chave estrangeira) e lá estiverON DELETE CASCADE
definido, eles também devem ser eliminados (e todos os descendentes, desde que haja um efeito cascata definido).A
FOREIGN KEY
própria restrição também pode ser descrita comoAllow No Orphans!
(em primeiro lugar). NãoChild
deve ser permitido (escrito) na tabela filho se não tiver umParent
(uma linha na tabela pai).Para consistência, o
ON DELETE RESTRICT
pode ser traduzido para o (menos agressivo)You Can't Kill Parents!
Somente linhas sem filhos podem ser eliminadas (excluídas).ON DELETE CASCADE é uma cláusula opcional em uma declaração de chave estrangeira. Assim vai com a declaração de chave estrangeira. (Significando, na tabela "filho".)
Uma maneira de interpretar uma declaração de chave estrangeira é: "Todos os valores válidos para esta coluna vêm de 'that_column' em 'that_table'." Quando você exclui uma linha na tabela "filho", ninguém se importa. Não afeta a integridade dos dados.
Quando você exclui uma linha da tabela "pai" -- de "that_table" -- você remove um valor válido dos valores possíveis para a tabela "filho". Para manter a integridade dos dados, você precisa fazer algo na tabela "filho". Exclusões em cascata é uma coisa que você pode fazer.
Capítulo e versículo, dos documentos do PostgreSQL .
Especificações SQL:2011
Existem cinco opções para
ON DELETE
eON UPDATE
que podem ser aplicadas aoFOREIGN KEY
. Eles são chamados<referential actions>
, diretamente da especificação SQL:2011A chave estrangeira estabelece o relacionamento dependente. O
<referential action>
determina o que acontece quando o relacionamento é dissolvido.Exemplo / Metáfora / Explicação
Para este exemplo, vamos aceitar o modelo comum de sociedade e economia: onde cada
business
uma é uma empresa que mantém um relacionamento com a empresabourgeoisie
por meio de umfatcat_owner
.Se todos os
business
es são diretamente afetados porbourgeoisie
elesfatcat_owner
, então o que você faz depois da revolução dos trabalhadores quando você purga osfatcat_owner
e tem uma sociedade sem classes?Você tem algumas opções aqui,
Pare a revolução. Na linguagem SQL,
RESTRICT
. Algumas pessoas acreditam que este é o mal menor, mas geralmente estão erradas.Permita que continue. Nesse caso, quando a revolução acontecer, o SQL oferece quatro opções,
SET NULL
-- deixe em branco. Quem sabe, talvez o capitalismo seja restauradobourgeoisie
e os oligarcas preencham o rol dofatcat_owners
. Nota importante, a coluna deve serNULLABLE
(notNOT NULL
) ou isso nunca pode acontecer.SET DEFAULT
-- talvez você teve umDEFAULT
que lidou com isso? ADEFAULT
pode chamar uma função. Talvez seu esquema já esteja pronto para a revolução.CASCADE
-- não há controle de danos. Se obourgeoisie
vai, o mesmo acontece com obusiness
. Se uma empresa deve ter umfatcat_owner
, às vezes faz mais sentido perder os dados em vez de ter uma não empresa em umabusiness
tabela.NO ACTION
-- este é essencialmente um método de atrasar a verificação, no MySQL não é diferente deRESTRICT
, mas no PostgreSQL, você poderia fazerEm tal sistema, a restrição é validada somente antes que a transação seja confirmada. Isso pode resultar na interrupção da revolução, mas você pode se recuperar na transação - para algum grau de "recuperação".
Um simples mnemônico seria
ON DELETE do pai CASCADE [por exclusão] aqui
Isso informa quais exclusões (exclusões do pai) são cascateadas, para onde vai a instrução ON DELETE CASCADE (no filho) e o que é excluído (o filho).
bem, talvez possamos racionalizar a sintaxe. Vamos dar um exemplo em Python:
o que esta linha diz é on_delete do Pai (que é acidentalmente mencionado na declaração), por favor, desfaça a exclusão no filho. É por isso que a instrução CASCADE é definida no nível filho, marca os filhos que precisam ser excluídos
Por exemplo, se você tivesse outra classe
essa estrutura mostraria claramente quais das crianças precisam ser removidas (Child) e quais devem ficar (GrownUpChild), embora órfãs
[Editar: Dado o contexto da discussão, especificamente em casos de on_delete=models.CASCADE etc,] na verdade, muitas vezes é um comportamento desejado deixar filhos de um pai excluído, devido a razões de auditoria e relatórios, bem como a recuperação acidental exclusões. [é claro que o software de nível empresarial será construído em torno desse comportamento e sinalizará os registros excluídos como excluídos=1 em vez de realmente excluí-los e também não os incluirá em nenhuma consulta para o front-end, menos alguns relatórios especialmente projetados. Além disso, ele terá a função de limpar os registros excluídos==1 do banco de dados, que normalmente serão executados pelo administrador da interface do usuário, muitas vezes evitando qualquer envolvimento do lado do administrador do banco de dados.]