Ich muss zunächst klarstellen, dass die Statusspalte nicht den Status eines realen Elements widerspiegeln soll, das durch den Datensatz (Zeile) in der Tabelle dargestellt wird. Vielmehr soll der Status des Datensatzes selbst angezeigt werden.
Es kann so einfach wie Aktiv / Inaktiv oder kompliziert wie Genehmigt / Gelöscht / Gesperrt / Ausstehend / Abgelehnt usw. sein. Der Status kann in einer booleschen / kurzen Ganzzahlspalte oder einer Einzelzeichenspalte mit Zuordnungen wie true
/ 1
= Aktiv oder gespeichert werden A
= Genehmigt.
Die Grundidee besteht darin, in der Anwendung eine Unterstützung für den Papierkorb- / Papierkorb-ähnliche Wiederherstellung bereitzustellen (und diese in der Datenbank zu simulieren). Wenn es eine Front-End-GUI oder eine andere Schnittstelle gibt, die einem Benutzer das "Löschen" von Datensätzen ermöglichen soll, wird der Datensatz in der Tabelle nicht tatsächlich gelöscht, sondern der Datensatzstatus wird einfach in Inaktiv oder Gelöscht geändert. Wenn die Schnittstelle Datensätze abruft, werden immer die Datensätze abgerufen, die nur der Bedingung entsprechen, dass der Status Aktiv oder Genehmigt lautet.
Wenn der Benutzer einen Fehler macht und der "gelöschte" Datensatz (aus Benutzersicht) wiederhergestellt werden muss, kann ein Datenbankadministrator den Datensatz problemlos auf "Aktiv" oder "Genehmigt" zurücksetzen. Dies ist besser, als nach Sicherungen zu suchen und hoffentlich den ursprünglichen Datensatz zu finden Dort. Über die Benutzeroberfläche selbst kann der Benutzer gelöschte Datensätze in einer separaten Ansicht anzeigen und bei Bedarf wiederherstellen oder sogar dauerhaft löschen (Löschen des tatsächlichen Datensatzes).
Meine Fragen:
- Ist das eine gute oder eine schlechte Praxis?
- Beeinflusst es die Normalisierung der Daten?
- Was sind die potenziellen Gefahren?
- Gibt es eine alternative Methode, um dasselbe Ziel zu erreichen? (siehe Anmerkung)
- Wie kann die Datenbank eindeutige Einschränkungen für die Daten nur für einen bestimmten Status erzwingen (für andere Status jedoch eine beliebige Anzahl von Duplikaten zulassen)?
- Warum bieten Datenbanken keine "Papierkorb" -Funktion oder Tabellenverfolgung / -wiederherstellung von Haus aus, sodass die Benutzeroberflächen die tatsächlichen Datensätze problemlos löschen können?
Hinweis: Ich habe gelesen, dass eine separate Verlaufstabelle verwaltet werden muss, was jedoch hinsichtlich des Speichers und der Notwendigkeit, Trigger zu generieren und die Trigger mit dem Schema der verfolgten Tabelle auf dem neuesten Stand zu halten, schlimmer zu sein scheint.
quelle
Antworten:
Ich kenne das als "Soft Delete"; Nur einen Datensatz als "gelöscht" markieren, obwohl dies nicht der Fall ist.
Es hängt davon ab, ob.
Wenn dies etwas ist, das Ihre Benutzer [sehr] brauchen, dann ist es wahrscheinlich eine gute Sache. In den allermeisten Fällen würde ich jedoch argumentieren, dass es [viel] Overhead für wenig Nutzen hinzufügt.
Nein, aber dies wirkt sich auf die Indizierung dieser Daten aus.
Stellen Sie sicher, dass Sie die Spalte "Gelöscht" in Ihre Indizes aufnehmen, damit diese Zeilen in Ihren Abfragen so früh wie möglich ausgeschlossen werden.
Ihre Daten werden etwas komplexer. Alles, was sich irgendwo in der Nähe der Daten befindet, muss über diese zusätzlichen "nicht wirklich vorhandenen" Datensätze "Bescheid wissen". Oder Sie müssen Ansichten für die Tabellen erstellen, die diese Zeilen ausschließen, und diese Ansichten beispielsweise in Ihrem Berichterstellungstool Ihrer Wahl verwenden.
Ihre Datenbank kann an Größe zunehmen. Wenn Sie diese Zeilen nicht wirklich löschen, sind sie immer noch vorhanden und belegen Speicherplatz. Dies kann ein Problem sein oder auch nicht, insbesondere, da Sie sie in Ihre Indizes aufgenommen haben, sodass der von ihnen belegte Speicherplatz vervielfacht wird.
Nicht wirklich, nein.
Nicht einfach. Die deklarative referenzielle Integrität (Fremdschlüsselklauseln) ist der sauberste Weg, dies zu implementieren, und es ist für Dinge wie Berichterstellungstools einfach, diese Regeln aufzunehmen, um die Beziehungen zwischen Tabellen zu bestimmen. Solche Regeln gelten für alle Datensätze, unabhängig vom "Status" (und daran führt kein Weg vorbei).
Die Alternative ist die Verwendung von Triggern, Ausschnitten aus dem Prozedurcode, die die referenzielle Integrität zwischen Tabellen erzwingen und alle cleveren, bedingten Aufgaben erledigen, die Sie benötigen. Das ist gut für Ihren speziellen Fall, aber die meisten Vorteile von Declarative RI gehen aus dem Fenster - es gibt keine [extern] erkennbaren Beziehungen zwischen Ihren Tabellen. Das ist alles "versteckt" in den Auslösern.
Warum sollten sie?
Dies sind schließlich Datenbanken, keine Dateisysteme oder Tabellenkalkulationen.
Was sie tun, können sie sehr, sehr gut.
Was sie nicht tun, war wahrscheinlich nicht sehr gefragt.
quelle
Es ist eine Übung. Ob es gut oder schlecht ist, hängt stark von Ihrer Anwendung ab und davon, wie häufig Sie wirklich ein "Undelete" ausführen müssen / möchten. Ich wäre ziemlich zweifelhaft, ob ich diese Art von Spalten für jede Tabelle in das System aufnehmen möchte - es ist sehr unwahrscheinlich, dass Sie wirklich die Mühe machen, Undelete für jede Tabelle im System zu implementieren. Und es ist eine Implementierung erforderlich. In den allermeisten Fällen wird nicht eine einzelne Zeile aus einer einzelnen Tabelle wiederhergestellt, sondern es werden untergeordnete Tabellen durchsucht, um die Zeilen wiederherzustellen und die zugehörigen Tabellen zu aktualisieren.
Bei den meisten anderen Fragen ist die Implementierung stark abhängig. Beispielsweise bietet Oracle verschiedene Methoden, um alle Änderungen an einer Tabelle nachzuverfolgen. Flashback Data Archive (FDA, auch als Total Recall bezeichnet) ist der neueste Ansatz, um eine vollständige Historie jeder Version einer Zeile und eine datenbankinterne Archivierung für die Implementierung zu verwalten das Soft-Delete-Muster. Andere Datenbanken bieten möglicherweise andere Möglichkeiten zum Implementieren des Musters. Abhängig von der Datenbank und der Art und Weise, wie Sie das vorläufige Löschen implementieren, hat dies verschiedene Auswirkungen auf die Leistung, ob und wie Einschränkungen erzwungen werden können usw. Wenn es sich um Oracle handelt, können Sie beispielsweise eine Menge mit funktionsbasierten Indizes tun In SQL Server können Sie häufig gefilterte Indizes für ähnliche Zwecke verwenden.
quelle
In MRP / ERP-Systemen wird häufig das Feld "Zum Löschen vorgemerkt" verwendet.
Beispielsweise kann es sinnvoll sein, einen Teil- oder Bestandsdatensatz zu markieren, der nicht mehr als inaktiv verkauft wird, mit dem jedoch noch ausstehende Bestellungen verbunden sind. Eine echte Löschung des Datensatzes kann sich auf noch nicht versendete Aufträge, noch nicht gebuchte Ledger-Einträge, Verlaufstabellen, die erst zum Monatsende erstellt werden, usw. auswirken. Viele Systeme können das Löschen eines Datensatzes nur zulassen, wenn eine Serie erfolgreich abgeschlossen wurde von Validierungen gegen andere Tabellen. Wenn Sie Löschungen durch Ihre Beziehungen kaskadieren, kann ein echtes Löschen sogar noch destruktiver sein.
Indem Sie den Datensatz zum Löschen markieren, setzen Sie stattdessen eine eindeutige Absichtsmarkierung in den Datensatz. Später kann ein geplanter Task den Datensatz löschen, wenn überprüft wird, dass nicht mehr alle zugehörigen Tabellen auf ihn verweisen.
Ein ähnlicher Fall könnte für dieses Merkmal bei einer Kundentabelle und anderen "Langzeittabellen" gemacht werden. Es ist sogar bei volatileren Tabellen wie Aufträgen sinnvoll, obwohl der Name der Flagge so etwas wie "versendet" oder "storniert" werden kann. Es hat die gleiche Funktion: Lösche es nicht in dieser Sekunde, sondern verwende es als Flag für das Löschprogramm, damit es versucht, das Löschen des Datensatzes in der Zukunft zu validieren.
quelle
Als alternative Lösung ermöglicht die Verwendung von Event-Sourcing ähnliche Ziele, ohne die Tabellenstruktur zu komplizieren, obwohl der Code zum Ändern Ihrer Daten dadurch etwas komplexer wird, da Sie die Änderung in ein Ereignis schreiben müssen, das in einem Ereignisverlauf gespeichert werden kann . Auf diese Weise können Sie die Datenbank zu jedem Zeitpunkt neu erstellen, was eine sehr nützliche Funktion sein kann.
(Ich glaube nicht, dass Sie dies mit "Verlaufstabelle" gemeint haben. Ich glaube, Sie haben damit gemeint, dass Sie einfach geänderte oder gelöschte Datensätze in eine andere Tabelle kopieren, bevor Sie sie ändern.)
quelle
Ich sehe und benutze dieses Muster häufig für diese Anwendungsfälle:
Das Problem besteht darin, die Datenintegrität zu erzwingen, wenn mehr als eine Anwendung oder ein Webdienst in Tabellen schreibt. Wie stellen Sie sicher, dass es für einen Fall nur einen aktuellen Status gibt? Wie Justin Cave betont, kann dies in Oracle durch Erstellen eines virtuellen Indexes auf der Grundlage einer Funktion erfolgen, jedoch mit zusätzlichem Aufwand für ein ursprünglich einfaches Konzept.
quelle
Dies ist eine gute Vorgehensweise, wenn Sie Ihre Daten für die Berichterstellung verwenden möchten (für jede ausreichend große Anwendung sind Berichte erforderlich).
Um Ihre Anwendung zu beschleunigen, sollten Sie Berichterstellungstools nicht in Ihrer Datenbank ausführen. Als solches müssten Sie eine Kopie / Synchronisierung mit einer anderen Datenbank durchführen.
Ich benutze
recordStatus
nur zwei ZuständeACTIVE
oderCANCELLED
in Kombination mit einemlastUpdatedOn
Zeitstempel. Ich benutzerecordStatus
eher alsstatus
was normalerweise eine geschäftliche Bedeutung hat.Wenn ich die Berichtsdatenbank mit der Anwendung synchronisiere, überprüfe ich anhand eines Filters
lastUpdatedOn
, welche auf der Berichtsseite ersetzt werden sollen.Auf der Berichtsseite werden die Felder
recordStatus
oder nichtlastUpdatedOn
angezeigt, da normalerweise nicht darüber berichtet wird. Wenn einCANCELLED
Status angezeigt wird, lösche ich den Datensatz auf der Berichtsseite, sodass nur aktive Datensätze vorhanden sind.Dies kann auf andere Arten von Speichern wie Archive oder Sicherungen ausgedehnt werden, bei denen eine nahezu vollständige Synchronisierung erforderlich ist. Die Berichterstattung ist jedoch der häufigste Zweck.
Beachten Sie Ihr Beispiel
Approved
,New
,Pending
ist keine gute Idee , als ein gemeinsames Feld zu setzen , da das ein Geschäft soll es weise nur, wo es Sinn macht Geschäft geht Bedeutung hat.Verwenden Sie für "Gesperrt"
versionNo
die Option, die eine optimistische Sperre für Ihren Datensatz bietet.Eine andere Option
recordStatus
istrecordActive
und hat es als eine gespeichert,boolean
die weniger Speicherplatz und weniger Indizierung beansprucht, aber ich wäre besorgt über zukünftige Bedürfnisse, die Sie möglicherweise nicht vorhersehen.quelle