Existe algum momento em que devemos evitar a exclusão em cascata?

11

No SQL Server 2008, há uma tabela Primária que está vinculada a três outras tabelas filho por 1 a muitos relacionamentos. Portanto, estamos pensando em usar a exclusão em cascata na tabela principal, para que todos os registros na tabela filha sejam removidos quando o registro da tabela principal for excluído.

  1. Então, excluir em cascata é uma escolha correta aqui?
  2. Quando o detele em cascata não deve ser usado?
Ramesh
fonte
3
Ninguém pode responder a isso sem conhecer seu caso de uso. A exclusão em cascata sempre tem o risco de os dados serem excluídos facilmente. Basicamente, eu o uso muito raramente, nos casos em que esse é o comportamento desejado. Estas são tabelas fortemente modificadas em geral.
Dez13

Respostas:

17

Geralmente, desconfio de exclusões em cascata (e outras ações automáticas que podem soltar / danificar dados), seja por gatilhos ou por ON <something> CASCADE. Tais instalações são muito poderosas, mas também potencialmente perigosas.

  • Então, excluir em cascata é uma escolha correta aqui?

Certamente faria o que você está procurando: remover registros relacionados quando um registro pai for removido, sem a necessidade de implementar outra lógica para garantir que os filhos sejam removidos primeiro, tornando seu código mais conciso. Todas as ações serão agrupadas em uma transação implícita; portanto, se algo bloquear o filho, a operação inteira será bloqueada, mantendo a integridade referencial com pouco ou nenhum esforço extra de codificação.

Verifique se o uso de exclusões em cascata e outras ações "nos bastidores" estão bem documentadas, para que futuros mantenedores do sistema estejam totalmente cientes disso.

  • Quando o detele em cascata não deve ser usado?

Não deve ser usado se você é paranóico como eu! Um ponto importante a considerar são os outros desenvolvedores que atualmente, ou no futuro, trabalham no seu código / banco de dados (daí o comentário acima sobre a documentação de comportamentos "ocultos").

Na minha experiência, é bastante comum as pessoas inexperientes usarem DELETEnovamente a INSERTfim de atualizar linhas, especialmente quando o que elas realmente querem é uma operação MERGE/ UPSERT(atualize as linhas existentes e crie novas onde uma linha com uma determinada chave não existe) e o DBMS não oferece suporte à mesclagem / upsert (ou eles desconhecem seu suporte). Sem ações em cascata, isso é perfeitamente seguro (ou ocorrerá um erro quando ameaça a integridade dos dados), mas se alguém fizer isso para linhas em uma tabela pai em que os FKs de referência tenhamON DELETE CASCADEdefinir então os dados relacionados serão excluídos como resultado da exclusão inicial e não serão substituídos - para que os dados sejam perdidos (mesmo que a exclusão e a inserção subsequente sejam agrupadas em transações explícitas, a cascata ocorrerá com a operação de exclusão - ela não será aguarde para ver se a transação substitui linhas na tabela pai nas instruções subseqüentes) e a cascata pode continuar por outros navios de relacionamento (por exemplo: excluir um supervisor sênior, sua equipe ser excluída por cascata, as equipes de suas equipes serão excluídas por cascata, todos os registros rastreados para todas essas pessoas são excluídos em cascata, ...). Sem a cascata ativada, você apenas obteria um erro aqui, em vez de os dados serem perdidos silenciosamente.

David Spillett
fonte
Haverá implicações no desempenho? Como adquirir um bloqueio e excluir manualmente seria melhor do que cascata?
Ramesh
Eu diria que haveria muito pouca diferença, supondo que você tenha o processo mais manual envolvido em uma transação explícita, o que você deve fazer por questões de consistência. Os métodos manual e automático (em cascata) serão afetados pelos níveis de bloqueio e isolamento quando a concorrência for considerada, é claro.
David Spillett 10/09
4

Acho que a resposta se resume a fazer ou não sentido para a sua situação, depende . Para a sua situação, faz sentido que as linhas na tabela 'filho' permaneçam se as linhas 'primárias' correspondentes forem removidas? Os dados na tabela filho não teriam sentido sem o pai? Nesse caso, a exclusão em cascata imporia a integridade referencial. Convém manter as linhas filho como um registro, um arquivo de atividades passadas (embora potencialmente você possa gravar essas linhas em outra tabela especialmente para esse fim).

Um exemplo que eu uso para ilustrar esse ponto é a relação médico / paciente. Um documento pode ter muitos pacientes. Um paciente só pode ser um paciente se tiver um médico. Se o médico for embora (deixar a clínica), algo terá que acontecer com os pacientes restantes. Uma possibilidade é que sejam expurgados. Outra é que um valor padrão substitui a referência do documento ou eles podem ser removidos da tabela principal e colocados em outro lugar. Como alternativa, nenhuma atividade ocorre e os pacientes permanecem intactos, como se o documento ainda estivesse presente. Depende do que você quer fazer.

Por experiência pessoal, pense cuidadosamente no design do banco de dados. Nesta semana, tive que fazer uma limpeza de registros órfãos em uma tabela que não apontava para lugar nenhum e estava literalmente ocupando espaço.

the_good_pony
fonte
Eu tenho que excluir os registros filho quando o registro pai for.
Ramesh
Se os registros deve ir completamente e eles não fazem sentido manter, em seguida, uma eliminação em cascata faria mais sentido em sua situação
the_good_pony
3

O uso da exclusão em cascata é uma questão de preferência pessoal, como nomear tabelas com nomes plurais ou não (Cliente x Cliente).

Eu preferiria nunca usar a exclusão em cascata. Alguns designs de banco de dados evitam a exclusão. Existem poucas justificativas para excluir dados de um banco de dados quando o espaço em disco é tão barato. Alguns designs de banco de dados definem um campo adicional "IsDeleted" em vez de excluir dados fisicamente.

Se você precisar excluir dados, o uso de procedimentos armazenados para gerenciar isso oferece mais transparência e controle. Seu aplicativo pode executar um procedimento armazenado que exclui do filho e do pai. Você não sabe como os requisitos de negócios mudarão com o tempo, de modo que os sps proporcionem mais versatilidade. Esse é o meu 2c.

sa555
fonte
É verdade que oferece mais versatilidade, mas também introduz um comportamento "oculto", o que significa que você precisa ter documentação adicional para esses sps (para que as pessoas saibam qual ação de negócios requer que sp) outra maneira poderia ser restringir os usuários do sql capaz de executar esses sps e não executar outras inserções / atualizações "simples".
DrCopyPaste