Ich versuche nur, ein paar Ideen zu bekommen, was die Leute für dieses Szenario tun. Wir haben eine Systemdatenbank (SQL Server 2008 R2) mit Tabellen und jede Tabelle hat ein Feld, das wir "Gelöscht" nennen können. Es ist im Grunde ein Bitfeld, wenn es eine 1 ist, wird der Datensatz gelöscht, wenn es eine 0 ist, wird es nicht gelöscht. Das Feld ist nicht nullbar und seine Standardeinstellung ist natürlich 0.
Wir können keine echten Löschungen in der Datenbank zulassen. Um dies zu umgehen, setzen wir ein Bitfeld (Gelöscht) auf true. In unserer Anwendung erhalten wir Fragen, die folgendermaßen aussehen:
SELECT blah FROM MyTable WHERE .. AND Deleted=0
Grundsätzlich filtern wir nach Datensätzen, sodass wir nur nicht gelöschte Zeilen erhalten. Unser Problem sind verwandte Datensätze, die kaskadiert werden müssen. Was bevorzugen die Leute, sollten wir dies im serverseitigen Code tun, damit beim Löschen eines Datensatzes alle zugehörigen Datensätze gelöscht werden (setzt das gelöschte Bitfeld auf true)? Oder sollte dies ein Trigger sein, der dieses Feld überprüfen und das Bitfeld für alle zugehörigen Datensätze auf 1 setzen muss?
Oder sind wir völlig auf dem falschen Weg?
Antworten:
Hier gibt es keine gute Lösung. Datenbanken bieten eine spezielle, effiziente kaskadierte Löschung über Fremdschlüssel. Wenn jedoch, wie Sie sagen, die tatsächliche Löschung keine Option ist, können Sie diese native Kaskadierung nicht nutzen.
Abhängig davon, ob Löschvorgänge häufig oder selten vorkommen, ist es effizienter, die Kaskadierung sofort (über zusätzliche Abfragen oder Trigger) zu emulieren, wenn Sie etwas pseudo-löschen, oder einfach immer alles aus der Datenbank abzurufen und nach dem Löschen zu filtern Flag in der Geschäftslogik.
Persönlich habe ich immer eine dritte Option verwendet: Auf alle Nebendatensätze kann nur über den Stammdatensatz zugegriffen werden. Dies geschieht nie, wenn dieser Datensatz sanft gelöscht wird. Sie müssen also nichts tun! Dies funktioniert natürlich nur, wenn Ihr Datenmodell ein strenger Baum ist (Kommentare werden nur beim Anzeigen des Produkts abgerufen, für das sie gelten, Benutzerrechte werden nur beim Verwalten des Benutzers abgerufen, zu dem sie gehören usw.) und nicht in einem Web (in dem Sie möglicherweise Fragen stellen alle Kommentare oder alle Berechtigungsdatensätze gleichgültig), aber ich finde, dass dies für überraschend viele Szenarien funktionieren kann.
quelle
Ich habe dies bereits mit Audit-Tabellen gemacht, bei denen jede Änderung an einer Datenbank in eine Audit-Spiegeltabelle (Einfügen / Aktualisieren / Löschen) geschrieben wird und die tatsächlichen realen Elemente kaskadiert gelöscht werden.
Die Spiegeltabellen sind mit der realen Tabelle identisch, wobei 3 Spalten hinzugefügt werden: "ChangeType", "User", "Date".
Dies hat den doppelten Vorteil, dass Daten korrekt gelöscht werden können, aber auch der Status der Datenbank zu jedem Zeitpunkt neu erstellt und der gesamte Verlauf eines Elements dokumentiert werden kann.
Ich füge hinzu, dass ich für das Kaskadieren von Löschvorgängen im Allgemeinen das Kaskadieren von Löschvorgängen auf dem Client bevorzuge. Der Server sollte nicht versuchen, diesbezüglich zu klug zu sein. Wenn ein Benutzer ein Unternehmen löscht und damit verbundene Probleme vorliegen, sollte die Aktion "Unternehmen löschen" ebenfalls gelöscht werden entsprechende Datensätze.
Dies war für ein Finanzmanagementsystem für eine große Investmentbank, daher war die Überprüfbarkeit ein kritisches Merkmal.
quelle
Tun Sie dies explizit für die Anweisung delete / undelete. Es gibt wahrscheinlich auch mehrere Szenarien, in denen Sie das Löschen nicht kaskadieren möchten.
Zum Beispiel; Betrachten Sie eine Person mit mehreren Adressen.
Löschen Sie die Person, setzen Sie einfach das Lösch-Flag auf die Person. Das Löschen muss nicht an Adressen kaskadiert werden, da wir diese Adressen bei der Wiederherstellung zurückhaben möchten.
Angenommen, die Person ist umgezogen, dann möchten wir das Löschflag nur für die alte Adresse aktualisieren und die anderen Adressen und die Person in Ruhe lassen. Eine Kaskadierung ist daher möglicherweise nicht immer erforderlich und hängt vom Szenario ab.
Ich denke, Sie müssen explizit sein, je nachdem, wie Ihr Modell eingerichtet ist und was Sie löschen.
quelle