Dilemma: Kaskadieren löschen oder Löschen beitreten

8

Es ist keine spezifische Frage, eher eine allgemeine Frage.

Wenn Sie mehrere Tabellen in einer 1: M-Beziehung löschen müssen, ist es besser, eine FK-Einschränkung mit einem kaskadierenden Löschvorgang zu erstellen oder die Tabellen in der Löschanweisung zu verknüpfen.

Ich hatte ein altes Projekt mit separaten delete-Anweisungen für verknüpfte Tabellen und einige Male wurden einige der Anweisungen nicht ausgeführt und die Datenintegrität wurde beeinträchtigt. Ich musste eine Entscheidung zwischen den beiden treffen, also überlegte ich ein bisschen, was eine bessere Lösung wäre.

Es gibt auch eine Option, um eine gespeicherte Prozedur oder eine Transaktion zu erstellen.

Ich suche also eine Meinung oder einen Rat ...?

    
Martin Taleski 19.10.2011, 12:38
quelle

4 Antworten

4

Wenn für Ihre Datenbank die richtige RI definiert ist, sollte die Integrität der Daten nicht beeinträchtigt werden. Alle verwandten Tabellen sollten eine deklarative RI aufweisen, was bedeutet, dass Sie nicht löschen können, während noch untergeordnete Elemente vorhanden sind.

Wenn Sie Code haben, der nur einige Zeilen löscht, dann ist das schlechtes Codieren und schlechtes Testen. Diese Art von Aktionen sollte eine einzelne Transaktion sein. Ihr Vorschlag, eine gespeicherte Prozedur zu verwenden, ist ein großartiger Ansatz zur Lösung dieses Problems und ist ziemlich Standard.

Wie bereits erwähnt, haben kaskadierende Trigger die Gefahr, Zeilen zu löschen, die jemand nicht löschen wollte. Beachten Sie, dass Personen manchmal von außerhalb Ihrer Anwendung auf Ihre Daten zugreifen, insbesondere bei der Behebung von Datenproblemen. Wenn jemand versehentlich versucht, den falschen Elternteil zu löschen, erhält er einen RI-Fehler, der gut ist. Wenn sie versehentlich versuchen, das falsche Elternelement zu löschen, löscht es nicht nur dieses Elternteil, sondern auch 20 Kinder in 5 anderen Tabellen, das ist schlecht.

Auch kaskadierende Löschungen sind sehr versteckt. Wenn ein Entwickler ein Löschelement für das übergeordnete Element codiert, sollten sie wissen, dass sie die gespeicherte Prozedur delete verwenden müssen, um auf untergeordnete Elemente zu achten. Es ist viel vorzuziehen, dass ein Entwickler keinen Code dagegen programmiert, einen Fehler erhält und seinen Code repariert (oder merkt, dass er nicht wirklich alles löschen möchte), als wenn ein Entwickler ein Delete einwerfen und haben möchte niemand merkt, dass es Kinder umbringt, bis der Code live gegangen ist.

IMO, ich bevorzuge es, meine Entwickler über die Anwendung zu informieren, anstatt es ihnen leichter zu machen, sie nicht zu kennen.

    
Tom H 31.10.2011, 17:58
quelle
7

Ich würde sagen, dass es sicherer ist, eine Kaskadenlöschung zu verwenden. Wenn Sie sich für die Verwendung von Joins entscheiden, müssen Sie daran denken, sie jedes Mal zu verwenden, wenn Sie etwas aus der übergeordneten Tabelle löschen. Und selbst wenn Sie diszipliniert genug sind, um das zu tun, können Sie sich nicht sicher sein, ob es Ihre Kollegen oder Leute sind, die Ihre Software in Zukunft unterstützen werden. Auch das Codieren dieses Wissens über Tabellenbeziehungen verstößt mehr als einmal gegen das DRY-Prinzip.

Wenn Sie jedoch eine Kaskadenlöschung verwenden, muss sich niemand an irgendetwas erinnern, und untergeordnete Zeilen werden immer nach Bedarf gelöscht.

    
socha23 19.10.2011 12:49
quelle
4

Kaskadenlöschung verursacht viele Probleme und ist daher extrem gefährlich. Ich würde es nicht empfehlen. Angenommen, ich muss den Datensatz löschen, der Millionen von Kinddatensätzen enthält. Sie könnten die Datenbank sperren und für Stunden unbrauchbar machen. Ich kenne nur sehr wenige dbas, die zulassen, dass Kaskadenlöschung in ihren Datenbanken verwendet wird.

Als nächstes hilft es nicht bei der Datenintegrität, wenn Sie die FKs definiert haben. Ein Löschen mit noch vorhandenen Kinddatensätzen wird fehlschlagen, was eine gute Sache ist. Ich möchte, dass der Kunde zum Löschen fehlschlägt, wenn er zum Beispiel bestehende Bestellungen hat. Cascade delete, das gedankenlos verwendet wird (wie es normalerweise in meiner Erfahrung ist), kann dazu führen, dass Dinge gelöscht werden, die Sie wirklich nicht löschen möchten.

    
HLGEM 19.10.2011 13:39
quelle
0

Benutze beide!

"Verbundene" manuelle Löschungen sind normalerweise besser, um Deadlocks und andere Konkurrenzprobleme zu vermeiden, da Sie die Löschvorgänge in kleinere Arbeitseinheiten aufteilen können. Wenn Sie Streit haben, ist es definitiv einfacher, die Ursache des Konflikts zu finden.

Wie bereits erwähnt, garantiert "Delete Cascade" absolut die referentielle Integrität.

Verwenden Sie also beide - führen Sie explizite Löschungen der "Kinder" in verbundenen sqls durch, um Deadlocks und Leistungsprobleme zu vermeiden. Lassen Sie "CASCADE DELETE" aktiviert, um alles zu erfassen, was Sie verpasst haben. Da beim Löschen des Elternteils keine Kinder mehr übrig sein sollten, kostet das nichts, es sei denn, Sie haben mit Ihren Löschungen einen Fehler gemacht. In diesem Fall lohnt es sich, die referentielle Integrität beizubehalten.

    
James Anderson 01.11.2011 01:57
quelle

Tags und Links