Ich habe eine Reihe von Fragen wie diese gesehen , in denen ich um Rat gefragt wurde, wie man Enums in DB speichert. Aber ich frage mich, warum Sie das tun würden. Nehmen wir also an, ich habe eine Entität Person
mit einem gender
Feld und einer Gender
Aufzählung. Dann hat meine Personentabelle eine Spalte Geschlecht.
Abgesehen von dem offensichtlichen Grund für die Durchsetzung der Korrektheit sehe ich nicht, warum ich eine zusätzliche Tabelle erstellen würde, um gender
das abzubilden, was ich bereits in meiner Anwendung habe. Und ich mag diese Vervielfältigung nicht wirklich.
Antworten:
Nehmen wir ein weiteres Beispiel, das weniger mit Vorstellungen und Erwartungen behaftet ist. Ich habe hier eine Aufzählung, und das sind die Prioritäten für einen Fehler.
Welchen Wert speichern Sie in der Datenbank?
Also, ich könnte zu speichern
'C'
,'H'
,'M'
, und'L'
in der Datenbank. Oder'HIGH'
so weiter. Dies hat das Problem der Eingabe von Zeichenfolgen . Es gibt einen bekannten Satz von gültigen Werten, und wenn Sie nicht diesen Satz in der Datenbank zu speichern, kann es schwierig sein , mit zu arbeiten.Warum speichern Sie die Daten im Code?
Sie haben
List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'};
oder etwas in diesem Sinne im Code. Dies bedeutet, dass Sie verschiedene Zuordnungen dieser Daten zum richtigen Format haben (Sie fügen alle Großbuchstaben in die Datenbank ein, aber Sie zeigen sie als anCritical
). Ihr Code ist jetzt auch schwer zu lokalisieren. Sie haben die Datenbankdarstellung der Idee an eine im Code gespeicherte Zeichenfolge gebunden.Überall dort, wo Sie auf diese Liste zugreifen müssen, müssen Sie entweder über Codeduplizierung oder eine Klasse mit einer Reihe von Konstanten verfügen. Beides sind keine guten Optionen. Man sollte auch nicht vergessen, dass es andere Anwendungen gibt, die diese Daten verwenden (die möglicherweise in anderen Sprachen geschrieben sind - die Java-Webanwendung verwendet ein Crystal Reports- Berichtssystem und einen Perl- Batch-Job, der Daten einspeist). Das Berichtsmodul muss die gültige Liste der Daten kennen (was passiert, wenn
'LOW'
keine Priorität markiert ist und Sie wissen müssen, dass dies eine gültige Priorität für den Bericht ist?), Und der Batch-Job muss die Informationen darüber enthalten, welche Daten gültig sind Werte sind.Hypothetisch könnte man sagen "Wir sind ein einsprachiger Shop - alles ist in Java geschrieben" und haben eine einzige .jar-Datei, die diese Informationen enthält - aber jetzt bedeutet dies, dass Ihre Anwendungen eng miteinander verbunden sind und diese .jar-Datei enthält die Daten. Sie müssen den Berichterstellungsteil und den Stapelaktualisierungsteil zusammen mit der Webanwendung bei jeder Änderung freigeben - und hoffen , dass diese Freigabe für alle Teile reibungslos verläuft.
Was passiert, wenn Ihr Chef eine andere Priorität haben möchte?
Ihr Chef ist heute vorbei gekommen. Es gibt eine neue Priorität -
CEO
. Jetzt müssen Sie den gesamten Code ändern , eine Neukompilierung durchführen und erneut implementieren.Mit der Methode "Aufzählung in der Tabelle" aktualisieren Sie die Aufzählungsliste, um eine neue Priorität zu erhalten. Der gesamte Code, der die Liste abruft, ruft sie aus der Datenbank ab.
Daten stehen selten allein
Bei Prioritäten werden die Daten in andere Tabellen übernommen, die möglicherweise Informationen zu Workflows enthalten, oder wer kann diese Priorität festlegen oder so weiter.
Kehren Sie kurz zum Geschlecht zurück, wie in der Frage erwähnt: Geschlecht hat einen Link zu den verwendeten Pronomen:
he/his/him
undshe/hers/her
... und Sie möchten vermeiden, dass dies hart in den Code selbst codiert wird. Und dann kommt dein Chef vorbei und du musst hinzufügen, dass du das'OTHER'
Geschlecht hast (um es einfach zu halten) und dass du dieses Geschlecht in Beziehung setzen musst zuthey/their/them
... und dein Chef sieht, was Facebook hat und ... na ja.Indem Sie sich statt auf eine Aufzählungstabelle auf ein Zeichenfolgenbit beschränken, müssen Sie diese Zeichenfolge jetzt in einer Reihe anderer Tabellen replizieren, um diese Beziehung zwischen den Daten und ihren anderen Bits aufrechtzuerhalten.
Was ist mit anderen Datenspeichern?
Egal, wo Sie dies speichern, das gleiche Prinzip besteht.
priorities.prop
, die die Prioritätenliste enthält. Sie lesen diese Liste aus einer Eigenschaftendatei ein.Sie könnten eine Dokumentenspeicher-Datenbank (wie CouchDB ) haben, die einen Eintrag für hat
enums
(und dann eine Validierungsfunktion in JavaScript schreiben ):Sie könnten eine XML-Datei mit einem gewissen Schema haben:
Die Kernidee ist die gleiche. Im Datenspeicher selbst muss die Liste der gültigen Werte gespeichert und erzwungen werden. Indem Sie es hier platzieren, ist es einfacher, über den Code und die Daten nachzudenken. Sie müssen nicht jedes Mal defensiv überprüfen, was Sie haben (Groß- oder Kleinschreibung? Warum gibt es einen
chritical
Typ in dieser Spalte? Usw.), weil Sie wissen, was Sie vom Datenspeicher zurückerhalten Genau das, was der Datenspeicher von Ihnen erwartet - und Sie können den Datenspeicher nach einer Liste gültiger Werte abfragen.Das wegnehmen
Der Satz gültiger Werte ist Daten , kein Code. Sie tun müssen , streben DRY Code - aber die Frage der Vervielfältigung ist , dass Sie die duplizieren Daten in dem Code, anstatt seinen Platz als Daten zu respektieren und sie in einer Datenbank zu speichern.
Es erleichtert mehrere Anwendungen gegen den Datenspeicher zu schreiben und vermeidet Instanzen mit dem Sie alles benötigen bereitstellen , die eng an die Daten gekoppelt ist , sich - weil Sie nicht haben , um Ihren Code zu den Daten gekoppelt.
Dies erleichtert das Testen von Anwendungen, da Sie nicht die gesamte Anwendung erneut testen müssen, wenn die
CEO
Priorität hinzugefügt wird - da Sie keinen Code haben, der sich um den tatsächlichen Wert der Priorität kümmert.Durch die Möglichkeit, unabhängig voneinander über den Code und die Daten nachzudenken, ist es einfacher, Fehler bei der Wartung zu finden und zu beheben.
quelle
Welche davon führen Ihrer Meinung nach eher zu Fehlern beim Lesen der Abfrage?
Oder
In SQL werden Aufzählungstabellen erstellt, da letztere besser lesbar sind. Dies führt zu weniger Fehlern beim Schreiben und Verwalten von SQL.
Sie könnten Gender direkt zu einer Zeichenfolge machen
Person
, aber dann müssten Sie versuchen, die Groß- und Kleinschreibung durchzusetzen. Sie können auch den Speichertreffer für die Tabelle und die Abfragezeit aufgrund des Unterschieds zwischen Zeichenfolgen und Ganzzahlen erhöhen, je nachdem, wie großartig Ihre DB bei der Optimierung von Dingen ist.quelle
Ich kann nicht glauben, dass die Leute das noch nicht erwähnt haben.
Fremde Schlüssel
Indem Sie die Aufzählung in Ihrer Datenbank behalten und der Tabelle einen Fremdschlüssel hinzufügen, der einen Aufzählungswert enthält, stellen Sie sicher, dass kein Code jemals falsche Werte für diese Spalte eingibt. Dies hilft Ihrer Datenintegrität und ist der offensichtlichste Grund, warum Sie IMO Tabellen für Aufzählungen haben sollten.
quelle
Ich bin im Lager, das mit dir übereinstimmt. Wenn Sie eine Gender-Aufzählung in Ihrem Code und einen tblGender in Ihrer Datenbank haben, können Probleme bei der Wartung auftreten. Sie müssen dokumentieren, dass diese beiden Entitäten dieselben Werte haben sollten, und daher müssen alle Änderungen, die Sie an einer vornehmen, auch an der anderen vorgenommen werden.
Anschließend müssen Sie die Enum-Werte wie folgt an Ihre gespeicherten Prozeduren übergeben:
Überlegen Sie sich jedoch, wie Sie dies tun würden, wenn Sie diese Werte in einer Datenbanktabelle speichern würden:
Sicher, relationale Datenbanken werden unter Berücksichtigung von Joins erstellt, aber welche Abfrage ist leichter zu lesen?
Hier ist eine weitere Beispielabfrage:
Vergleichen Sie das damit:
Hier ist noch eine andere Beispielabfrage:
Beachten Sie, dass Sie in diesem Beispiel die Geschlechtszelle in Ihren Ergebnissen von einem Int in eine Enumeration konvertieren müssen. Diese Konvertierungen sind jedoch einfach. Vergleichen Sie das damit:
Alle diese Abfragen sind kleiner und leichter zu verwalten, wenn Sie die Idee haben, die Enum-Definitionen aus der Datenbank herauszuhalten.
quelle
Ich würde eine Genders-Tabelle erstellen, um sie für die Datenanalyse zu verwenden. Ich könnte alle männlichen oder weiblichen Personen in der Datenbank nachschlagen, um einen Bericht zu erstellen. Je mehr Möglichkeiten Sie haben, Ihre Daten anzuzeigen, desto einfacher ist es, Trendinformationen zu ermitteln. Offensichtlich ist dies eine sehr einfache Aufzählung, aber für komplexe Aufzählungen (wie die Länder der Welt oder Staaten) ist es einfacher, spezielle Berichte zu erstellen.
quelle
Zunächst müssen Sie entscheiden, ob die Datenbank immer nur von einer Anwendung verwendet wird oder ob mehrere Anwendungen sie möglicherweise verwenden. In einigen Fällen ist eine Datenbank nichts anderes als ein Dateiformat für eine Anwendung (SQLite-Datenbanken können in dieser Hinsicht häufig verwendet werden). In diesem Fall kann das Duplizieren der Enum-Definition als Tabelle häufig in Ordnung und sinnvoller sein.
Sobald Sie jedoch die Möglichkeit in Betracht ziehen möchten, dass mehrere Anwendungen auf die Datenbank zugreifen, ist eine Tabelle für die Aufzählung sehr sinnvoll (die anderen Antworten gehen ausführlicher auf das Warum ein). Die andere zu berücksichtigende Sache werden Sie oder ein anderer Entwickler die rohen Datenbankdaten betrachten wollen. In diesem Fall kann dies als eine andere Anwendungsverwendung angesehen werden (nur eine, bei der die Laboranzeige Raw-SQL ist).
Wenn Sie die im Code definierte Enumeration (zur Überprüfung des saubereren Codes und der Kompilierungszeit) sowie eine Tabelle in der Datenbank haben, würde ich empfehlen, Komponententests hinzuzufügen, um zu überprüfen, ob die beiden synchron sind.
quelle
Wenn Sie über eine Code-Enumeration verfügen, mit der die Geschäftslogik im Code gesteuert wird, sollten Sie aus den oben / unten aufgeführten Gründen dennoch eine Tabelle erstellen, um die Daten in der Datenbank darzustellen. Mit den folgenden Tipps können Sie sicherstellen, dass Ihre DB-Werte mit den Codewerten synchron bleiben:
Machen Sie das ID-Feld in der Tabelle nicht zu einer Identitätsspalte. Fügen Sie ID und Beschreibung als Felder ein.
Machen Sie in der Tabelle etwas anderes, damit die Entwickler wissen, dass die Werte semistatisch / an eine Code-Aufzählung gebunden sind. In allen anderen Nachschlagetabellen (in der Regel können Werte von Benutzern hinzugefügt werden) habe ich in der Regel ein LastChangedDateTime und ein LastChangedBy, aber wenn sie nicht in Aufzählungstabellen enthalten sind, kann ich mich daran erinnern, dass sie nur von Entwicklern geändert werden können. Dokumentieren Sie dies.
Erstellen Sie einen Bestätigungscode, mit dem überprüft wird, ob sich jeder Wert in der Aufzählung in der entsprechenden Tabelle befindet und nur diese Werte in der entsprechenden Tabelle enthalten sind. Wenn Sie automatisierte "Health-Tests" für Anwendungen haben, die nach der Erstellung ausgeführt werden, sind Sie dort richtig. Andernfalls wird der Code beim Start der Anwendung automatisch ausgeführt, wenn die Anwendung in der IDE ausgeführt wird.
Create Production liefert SQL-Skripte, die dasselbe tun, jedoch aus der Datenbank heraus. Bei korrekter Erstellung helfen sie auch bei der Migration der Umgebung.
quelle
Kommt auch darauf an, wer auf die Daten zugreift. Wenn Sie nur eine Anwendung haben, ist dies möglicherweise in Ordnung. Wenn Sie ein Data Warehouse oder ein Berichtssystem hinzufügen. Sie müssen wissen, was dieser Code bedeutet, was die vom Menschen redierbare Version des Codes ist.
Normalerweise würde die Typentabelle nicht als Enumeration im Code dupliziert. Sie können die Typentabelle in eine zwischengespeicherte Liste laden.
Typ kommt und geht oft. Sie benötigen ein Datum, an dem der neue Typ hinzugefügt wurde. Wissen, wann ein bestimmter Typ entfernt wurde. Zeigen Sie es nur bei Bedarf an. Was ist, wenn ein Klient "Transgender" als Geschlecht haben möchte, andere Klienten jedoch nicht? All diese Informationen werden am besten in der Datenbank gespeichert.
quelle