In SQL Server 2008 gibt es eine Primärtabelle, die mit drei anderen untergeordneten Tabellen durch eine Beziehung von 1 zu vielen verknüpft ist. Wir denken also darüber nach, Cascading delete in der Primärtabelle zu verwenden, damit alle Datensätze in der untergeordneten Tabelle entfernt werden, wenn der Datensatz aus der Primärtabelle gelöscht wird.
- Ist das kaskadierende Löschen hier eine richtige Wahl?
- Wann sollte kaskadierende Detele nicht verwendet werden?
Antworten:
Ich bin generell vorsichtig bei kaskadierten Löschvorgängen (und anderen automatischen Aktionen, die Daten löschen oder beschädigen könnten), entweder über Trigger oder
ON <something> CASCADE
. Solche Einrichtungen sind sehr leistungsfähig, aber auch potenziell gefährlich.Es würde sicherlich das tun, wonach Sie suchen: Entfernen Sie verwandte Datensätze, wenn ein übergeordneter Datensatz entfernt wird, ohne dass Sie eine andere Logik implementieren müssen, um sicherzustellen, dass Kinder zuerst entfernt werden, wodurch Ihr Code präziser wird. Alle Aktionen werden in eine implizite Transaktion eingeschlossen. Wenn also etwas blockiert, löscht das Kind die gesamte Operation, wodurch die referenzielle Integrität mit geringem oder keinem zusätzlichen Codierungsaufwand aufrechterhalten wird.
Stellen Sie sicher, dass Ihre Verwendung von kaskadierten Löschvorgängen und anderen Aktionen "hinter den Kulissen" gut dokumentiert ist, damit zukünftige Systembetreuer sich dessen voll bewusst sind.
Es sollte nicht verwendet werden, wenn Sie wie ich paranoid sind! Ein wichtiger Punkt, den Sie berücksichtigen sollten, sind die anderen Entwickler, die derzeit oder in Zukunft an Ihrem Code / Ihrer Datenbank arbeiten (daher der obige Kommentar zur Dokumentation "versteckter" Verhaltensweisen).
Es ist ganz in meiner Erfahrung gemeinsam für unerfahrene Menschen zu verwenden ,
DELETE
dann re-INSERT
zu aktualisieren , um Reihen, vor allem , wenn , was sie wirklich wollen , ist einMERGE
/UPSERT
Betrieb (Update vorhandene Zeilen und neue zu schaffen , in der eine Zeile mit einem bestimmten Schlüssel nicht existiert) und das DBMS unterstützt Merge / Upsert nicht (oder sie wissen nichts von seiner Unterstützung). Ohne kaskadierte Aktionen ist dies absolut sicher (oder es tritt ein Fehler auf, wenn die Datenintegrität gefährdet wird), aber wenn jemand dies für Zeilen in einer übergeordneten Tabelle tut, in denen verweisende FKs vorhanden sindON DELETE CASCADE
Wenn dann festgelegt wird, werden verwandte Daten als Ergebnis des anfänglichen Löschens gelöscht und nicht ersetzt - so gehen Daten verloren (nicht, dass die Kaskade mit dem Löschvorgang stattfindet, selbst wenn das Löschen und das anschließende Einfügen in explizite Transaktionen eingeschlossen sind - dies wird nicht der Fall sein Warten Sie ab, ob die Transaktion die Zeilen in der übergeordneten Tabelle in nachfolgenden Anweisungen ersetzt.) Die Kaskade kann über andere Beziehungsschiffe fortgesetzt werden (z. B. Löschen eines leitenden Vorgesetzten, Löschen seines Teams durch Kaskade, Löschen der Teams seiner Teams durch Kaskade). Alle verfolgten Datensätze für all diese Personen werden durch Kaskade gelöscht, ...). Ohne aktivierte Kaskadierung würde hier nur ein Fehler angezeigt, anstatt dass die Daten stillschweigend verloren gehen.quelle
Ich denke, die Antwort läuft darauf hinaus, ob es für Ihre Situation Sinn macht oder nicht, es hängt davon ab . Ist es für Ihre Situation sinnvoll, dass die Zeilen in der 'untergeordneten' Tabelle erhalten bleiben, wenn die entsprechenden 'primären' Zeilen entfernt werden? Wären die Daten in der untergeordneten Tabelle ohne das übergeordnete Element bedeutungslos? Wenn ja, würde das kaskadierende Löschen die referenzielle Integrität erzwingen. Möglicherweise möchten Sie untergeordnete Zeilen als Datensatz aufbewahren, als Archiv vergangener Aktivitäten (obwohl Sie diese Zeilen möglicherweise speziell für diesen Zweck in eine andere Tabelle schreiben könnten).
Ein Beispiel, das ich zur Veranschaulichung dieses Punktes verwende, ist die Beziehung zwischen Arzt und Patient. Ein Arzt kann viele Patienten haben. Ein Patient kann nur ein Patient sein, wenn er einen Arzt hat. Wenn der Arzt geht (die Praxis verlässt) , muss den verbleibenden Patienten etwas passieren. Eine Möglichkeit ist, dass sie gelöscht werden. Ein weiterer Grund ist, dass ein Standardwert die Dokumentreferenz ersetzt oder sie aus der Haupttabelle entfernt und an einer anderen Stelle platziert werden können. Alternativ tritt keine Aktivität auf und die Patienten bleiben unberührt, als ob der Arzt noch anwesend wäre. Es kommt darauf an, was Sie tun möchten.
Denken Sie aus persönlicher Erfahrung sorgfältig über das Design der Datenbank nach. Diese Woche musste ich eine Bereinigung verwaister Aufzeichnungen in einer Tabelle durchführen, die auf nichts hinwies und buchstäblich Platz beanspruchte.
quelle
Die Verwendung des kaskadierenden Löschens ist eine Frage der persönlichen Präferenz, z. B. ob Tabellen mit mehreren Namen benannt werden sollen oder nicht (Kunde gegen Kunden).
Ich würde es vorziehen, niemals kaskadierendes Löschen zu verwenden. Einige Datenbankdesigns vermeiden das Löschen überhaupt. Es gibt nur wenige Gründe, Daten aus einer Datenbank zu löschen, wenn der Speicherplatz so billig ist. Einige Datenbankdesigns setzen ein zusätzliches Feld "IsDeleted", anstatt Daten physisch zu löschen.
Wenn Sie Daten löschen müssen, erhalten Sie durch die Verwendung gespeicherter Prozeduren mehr Transparenz und Kontrolle. Ihre Anwendung kann eine gespeicherte Prozedur ausführen, die vom untergeordneten und dann vom übergeordneten Element gelöscht wird. Sie wissen nicht, wie sich die Geschäftsanforderungen im Laufe der Zeit ändern werden, sodass sp's Ihnen mehr Vielseitigkeit bieten. Das ist mein 2c.
quelle