C'è un momento in cui dovremmo evitare l'eliminazione a cascata?


11

In SQL Server 2008 esiste una tabella primaria collegata ad altre tre tabelle figlio da 1 a molte relazioni. Pertanto, stiamo pensando di utilizzare l'eliminazione a cascata nella tabella principale, in modo che tutti i record nella tabella figlio vengano rimossi quando viene eliminato il record dalla tabella principale.

  1. Quindi, eliminare a cascata è una scelta corretta qui?
  2. Quando il detele in cascata non deve essere usato?

3
Nessuno può rispondere a questa domanda senza conoscere il tuo caso d'uso. L'eliminazione a cascata comporta sempre il rischio che i dati vengano eliminati facilmente. Fondamentalmente lo uso molto raramente, nei casi in cui questo è il comportamento desiderato. Si tratta in genere di tabelle fortemente modificate.
dezso

Risposte:


17

In genere sono diffidente nei confronti delle eliminazioni a cascata (e di altre azioni automatiche che potrebbero far cadere / danneggiare i dati), sia tramite trigger o ON <something> CASCADE. Tali strutture sono molto potenti, ma anche potenzialmente pericolose.

  • Quindi, eliminare a cascata è una scelta corretta qui?

Farebbe sicuramente quello che stai cercando di fare: rimuovere i record correlati quando viene rimosso un record principale, senza che sia necessario implementare qualsiasi altra logica per garantire che i bambini vengano rimossi per primi, quindi rendendo il codice più conciso. Tutte le azioni saranno racchiuse in una transazione implicita, quindi se qualcosa blocca il bambino elimina l'intera operazione viene bloccata, mantenendo l'integrità referenziale con uno sforzo di codifica minimo o nullo.

Assicurati che il tuo uso di eliminazioni in cascata e altre azioni "dietro le quinte" siano ben documentati in modo che i futuri manutentori del sistema ne siano pienamente consapevoli.

  • Quando il detele in cascata non deve essere usato?

Non dovrebbe essere usato se sei paranoico come me! Un punto chiave da considerare è gli altri sviluppatori che attualmente, o potrebbero in futuro, lavorano sul tuo codice / database (da qui il commento sopra sulla documentazione di eventuali comportamenti "nascosti").

È abbastanza comune nella mia esperienza per le persone inesperte usare DELETEquindi ri INSERT-aggiornare le righe, specialmente quando ciò che vogliono veramente è un'operazione MERGE/ UPSERT(aggiornare le righe esistenti e crearne di nuove in cui non esiste una riga con una determinata chiave) e il DBMS non supporta merge / upsert (o non sono a conoscenza del suo supporto). Senza azioni a cascata questo è perfettamente sicuro (o si verificherà un errore quando minaccia l'integrità dei dati) ma se qualcuno lo fa per le righe in una tabella padre in cui gli FK di riferimento hannoON DELETE CASCADEimpostare quindi i dati correlati verranno eliminati come risultato dell'eliminazione iniziale e non sostituiti - quindi i dati vengono persi (non che anche se l'eliminazione e l'inserimento successivo sono racchiusi in transazioni esplicite, la cascata si verifica con l'operazione di eliminazione - non lo farà attendi di vedere se la transazione sostituisce le righe nella tabella padre nelle dichiarazioni successive) e la cascata potrebbe continuare attraverso altre navi relazionali (ad esempio: elimina un supervisore senior, il suo team viene eliminato a cascata, i team dei suoi team vengono eliminati a cascata, tutti i record tracciati per tutte quelle persone vengono eliminati a cascata, ...). Senza il collegamento a cascata abilitato, qui verrebbe visualizzato un errore anziché la perdita silenziosa dei dati.


Ci saranno implicazioni sulle prestazioni? Come acquisire un lucchetto ed eliminarlo manualmente sarebbe meglio della cascata?
Ramesh,

Suppongo che ci sarebbero pochissime differenze, supponendo che tu abbia il processo più manuale racchiuso in una transazione esplicita che dovresti fare per problemi di coerenza. Sia i metodi manuali che automatici (a cascata) saranno influenzati dai livelli di blocco e isolamento una volta considerata la concorrenza, ovviamente.
David Spillett,

4

Immagino che la risposta si riduca al fatto che abbia o meno senso per la tua situazione, dipende . Per la tua situazione, ha senso che le righe nella tabella "figlio" rimangano se le corrispondenti righe "primarie" vanno? I dati nella tabella figlio sarebbero privi di significato senza il genitore? In tal caso, l'eliminazione a cascata imporrebbe l'integrità referenziale. Potresti voler mantenere le righe secondarie come record, un archivio di attività passate (anche se potenzialmente potresti scrivere queste righe su un'altra tabella appositamente per questo scopo).

Un esempio che uso per illustrare questo punto è la relazione medico / paziente. Un documento può avere molti pazienti. Un paziente può essere un paziente solo se ha un medico. Se il documento va (lascia la pratica), allora deve succedere qualcosa ai pazienti rimanenti. Una possibilità è che vengano purificati. Un altro è che un valore predefinito sostituisce il riferimento al documento o potrebbero essere rimossi dalla tabella principale e collocati altrove. In alternativa, non si verifica alcuna attività e i pazienti rimangono invariati, come se il documento fosse ancora presente. Dipende da cosa vuoi fare.

Per esperienza personale, riflettere attentamente sulla progettazione del database. Questa settimana ho dovuto eseguire una purga di dischi orfani in una tabella che non indicava da nessuna parte e stava letteralmente occupando spazio.


Devo eliminare i record figlio quando il record padre va.
Ramesh,

Se i record devono andare completamente e non hanno senso conservarli,
un'eliminazione

3

L'uso dell'eliminazione a cascata è una questione di preferenza personale, ad esempio se nominare le tabelle con nomi plurali o meno (Cliente vs Clienti).

Preferirei non usare mai l'eliminazione a cascata. Alcuni progetti di database evitano affatto la cancellazione. Ci sono alcune giustificazioni per eliminare i dati da un database quando lo spazio su disco è così economico. Alcuni progetti di database impostano un campo aggiuntivo "IsDeleted" anziché eliminare fisicamente i dati.

Se è necessario eliminare i dati, l'utilizzo delle procedure memorizzate per gestirlo offre maggiore trasparenza e controllo. L'applicazione può eseguire una procedura memorizzata che viene eliminata dal figlio e quindi dal genitore. Non sai come le esigenze aziendali cambieranno nel tempo, quindi sp ti darà maggiore versatilità. Questo è il mio 2c.


È vero, ti dà più versatilità, ma introduce anche comportamenti "nascosti", il che significa che devi avere documentazione aggiuntiva per quegli sps (in modo che ppl sappia quale azione aziendale richiede quale sp) un altro modo potrebbe essere quello di limitare gli utenti sql in grado di eseguire quegli sps e di non eseguire affatto altri inserimenti / aggiornamenti "semplici".
DrCopyPaste,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.