Bei vielen Anwendungen müssen Datensätze in ihren Tabellen den Status "Vollständig", "Entwurf", "Abgebrochen" haben. Wie können diese Status am besten gespeichert werden? Um zu veranschaulichen, was ich hier vorhabe, ist ein * sehr kurzes) Beispiel.
Ich habe eine einfache Blog-Anwendung und jeder Beitrag hat den Status "veröffentlicht", "Entwurf" oder "Ausstehend".
So wie ich es sehe, gibt es zwei Möglichkeiten, dies in der Datenbank zu modellieren.
- Die Post-Tabelle verfügt über ein Textfeld, das den Statustext enthält.
- Die Post-Tabelle verfügt über ein Statusfeld, das die ID eines Datensatzes in der PostStatus-Tabelle enthält
Das Blog-Beispiel hier ist ein sehr einfaches Beispiel. Wo eine Aufzählung (falls unterstützt) ausreichen könnte. Bei der Beantwortung der Frage möchte ich jedoch berücksichtigen, dass sich die Liste der Status jederzeit ändern kann, sodass weitere hinzugefügt oder entfernt werden können.
Kann jemand die Vor- / Nachteile der einzelnen erklären?
Prost!
Meine anfängliche Meinung dazu ist, dass es besser ist, eine andere Tabelle zu verwenden und den Status als besser für die Normalisierung nachzuschlagen, und mir wurde immer beigebracht, dass die Normalisierung für Datenbanken gut ist
quelle
Antworten:
Das Speichern des Status als Index in einer anderen Tabelle ist eine unnötige Komplikation. Speichern Sie den Status lesbar direkt in der Tabelle. Verwenden Sie im Anwendungscode Konstanten oder einen Aufzählungstyp. Dies führt zu einem einfacheren Anwendungscode und erleichtert das Debuggen der Datenschicht.
Dadurch werden die Daten nicht denormalisiert, sondern lediglich die Darstellung geändert. Wenn die Datenbank Aufzählungen direkt unterstützt, verwenden Sie diese. Verwenden Sie andernfalls eine Einschränkung, um die Spaltenwerte einzuschränken. Sie haben entweder eine direkte Einschränkung für die Spaltenwerte oder eine Fremdschlüsseleinschränkung.
Ja, möglicherweise müssen Sie den Status für verschiedene Benutzer unterschiedlich darstellen. Dies ist ein Präsentationsproblem, das in der Präsentationsschicht und nicht in der Persistenzschicht gelöst werden muss.
quelle
Das Speichern des Statustextes ist IMO keine gute Idee, da jemand entscheiden könnte, dass "vollständig" stattdessen als "fertig" bezeichnet werden soll, und Sie dann Ihre Datenbank aktualisieren müssen, das Programm durchsehen, wenn jemand den Text fest codiert hat usw.
Was ich in vielen Programmen gesehen habe, ist entweder ein numerischer Code (1 = neu, 2 = Entwurf, 3 = in Validierung, 4 = vollständig, 99 = storniert) oder ein kurzer alphanumerischer Code ("NEW", "DRA", "INV") "," COM "," CAN "). Letzteres macht den Code (im Programm oder in der Datenbank) besser lesbar, was im Allgemeinen eine gute Sache ist. Andererseits machen es numerische Codes einfach, Vergleiche beispielsweise "größer als" oder "kleiner als" durchzuführen
quelle
status.draft=Draught
Die drei Regeln relationaler Datenbanken:
Ihre Frage beantwortet sich also von selbst. Behalten Sie den Status in der eigenen Tabelle und verwenden Sie GUID / UUIDs als Ihre ID . Indizierte GUIDS sind sehr schnell und beheben die Probleme, die mit der Erhöhung von Zahlen verbunden sind. Mit einer ID können Sie coole Dinge tun, wie die DB nach allen abgeschlossenen Posts mit der ID zu fragen, und da Sie innerhalb des relationalen DB-Paradigmas arbeiten, ist es sehr schnell. Wenn Sie nur ein Feld haben, muss die DB jede einzelne Zeile durchlaufen und einen Textvergleich durchführen, möglicherweise mit Munging, und das ist sehr langsam.
Die Post-Status-Namen können sich ändern, weitere Informationen zum Post-Status können in die Tabelle aufgenommen werden. Alles funktioniert nur, wenn Sie normalisieren .
Beispielsweise können Sie Statusebenen als zusätzliche Informationen hinzufügen, die den Vergleich von ammoQ-Erwähnungen ermöglichen. Sie hängen jedoch nicht vom Positionierungsschlüssel ab, sodass die Statusebene neu angeordnet werden kann, ohne die Integrität der Datenbank zu beeinträchtigen. Sie können auch zusätzliche Ebenen einfügen. Dies ist ein ziemlicher Trick, wenn Sie die Ebene haben, die dem Autoincrementing-Schlüssel zugeordnet ist.
quelle
Ja, Sie sollten Option 2 wählen und eine PostStatus-Tabelle haben.
Abgesehen von all den Vorteilen, die in anderen Antworten erwähnt wurden.
Beachten Sie, dass die Status hinzugefügt oder entfernt werden müssen. In der PostStatus-Tabelle kann eine Spalte "Aktiviert" angezeigt werden. Wenn der Status entfernt wird, markieren Sie die Spalte "Aktiviert" als "N". Auf diese Weise können Sie dies tun Das Hinzufügen oder Entfernen von Status und auch die vorhandenen Datensätze bleiben ohne Probleme.
quelle
Zu den ansonsten aufschlussreichen Antworten möchte ich hinzufügen, dass für eine vollständige Normalisierung eine Änderung des Status einer Entität tatsächlich in einer separaten Entität modelliert wird, z. B. mit dem Namen "statusChange".
Sie benötigen eine zusätzliche Verknüpfung mit der statusChange-Entität, haben jedoch die Möglichkeit, zusätzliche Informationen hinzuzufügen, z. B. den Akteur, der die Änderung ausführt, mögliche Kommentare zum Grund für die Änderung und ein Datum, an dem die statusChange durchgeführt wird, und möglicherweise sogar wann es wird wirksam.
quelle
Die Verwendung von Text für den Status in der Datensatztabelle ist wahrscheinlich keine gute Idee, da sich dies ändern kann und es schwierig ist, Datenintegritätsprüfungen beim Einfügen / Aktualisieren durchzuführen. Wenn Sie ein DBMS mit einem Aufzählungsdatentyp verwenden, können Sie diesen stattdessen verwenden (Leistung wird wahrscheinlich nicht beeinträchtigt ... abhängig).
Wenn für Ihren Status Metadaten (Beschreibung, Erstellt von, Anzeigename, ...) erforderlich sind, müssen Sie den Status in einer separaten Tabelle speichern und einen Statusschlüssel in Ihrer Datensatztabelle haben (stellen Sie sicher, dass Sie einen Fremdschlüssel verwenden). Die ID muss nicht unbedingt eine Zahl sein, sondern nur die PK der Statustabelle. Wenn sich die Status in einer eigenen Tabelle befinden, können Sie sie gegebenenfalls für mehrere Datensatztypen (Tabellen) freigeben. Ich würde mir keine Sorgen um Leistungsprobleme machen, wenn Sie der Statustabelle beitreten.
Vermeiden Sie auf jeden Fall magische Zustände (1 für aktiv, 2 für gelöscht, ...). Dies beruht auf Dokumentation und Tradition, die immer dazu neigen, sich auf einer ausreichend großen Zeitachse zu verlaufen. Wenn Sie überhaupt numerische IDs verwenden, vergewissern Sie sich, dass irgendwo in Ihrer Datenbank eine Textverknüpfung vorhanden ist.
quelle
Hängt vom Zweck des Datenbankentwurfs ab.
Wenn Sie die Datenbank einfach so entwerfen, dass sie die Anwendung unterstützt (dh die Objekte (der Code) sind der Master aller), ist die Verwendung einer Aufzählung (oder einer Pseudo-Aufzählung für Klassen, die diese nicht unterstützen) und das Speichern des Namens der Aufzählung a Eine gute Idee, da Sie immer noch die Werte kontrollieren, die durch die Aufzählung zulässig sind, und die Tabelle ein wenig leichter lesbar machen, wenn Sie gezwungen sind, die Rohdaten anzuzeigen (was nicht so häufig der Fall ist, wenn der Code tatsächlich alle regiert). Aber wenn die Aufzählung markiert ist. Dann speichere ich in der Regel den Enum-Wert (Integer) ab.
quelle
Der Status ist sehr wichtig. Jedes Mal, wenn Sie Post-Informationen erhalten, müssen Sie den Status abrufen, oder Sie möchten Posts nach Status filtern. Wenn Sie in einer anderen Tabelle den Status haben, müssen Sie Verknüpfungen erstellen, um diese Informationen abzurufen. Dadurch wird die Leistung beeinträchtigt. Auf jeden Fall sollten Sie den Status in derselben Tabelle haben. Und legen Sie einen Index darauf! Sie können weiterhin Ganzzahlen als Status- oder vielleicht auch Enum-Feld verwenden.
quelle
Die richtige Lösung besteht darin, entweder einen Ereignisspeicher / eine Ereignisquelle mit CQRS oder eine Blockchain zu verwenden. Das Problem beim Erfassen von Ereignissen in einer RDB besteht darin, dass die RDB einen Snapshot eines einzelnen Ereignisses in der Zeit speichert und Dinge wie "Status / Zustände" Sequenzen von Mutationen sind, die sich im Laufe der Zeit entwickeln
quelle