Die Antwort hängt ein wenig davon ab, ob Sie auf Freeware wie PostGreSQL (nicht vollständig SQL-kompatibel) beschränkt sind oder ob Sie an SQL (dh SQL-kompatibel) und große Datenbanken denken.
In SQL-konform, Offene Architektur Datenbanken, wo viele Apps eine Datenbank verwenden und viele Benutzer unterschiedliche Berichtstools (nicht nur die Apps) verwenden, um auf die Daten zuzugreifen, Anforderungen an Standards, Normalisierung und offene Architektur sind wichtig.
Trotz der Leute, die versuchen, die Definition von "Normalisierung" usw. zu ändern, um sie ihrem sich ständig ändernden Zweck anzupassen, hat sich die Normalisierung (die Wissenschaft) nicht geändert.
-
wenn Sie Datenwerte haben wie {
Open; Closed; etc
} in Datentabellen wiederholt, das ist Datenduplizierung , ein einfacher Normalisierungsfehler:Wenn Sie diese Werte ändern, müssen Sie möglicherweise Millionen von Zeilen aktualisieren, was ein sehr eingeschränktes Design ist.-
Solche Werte sollten mit einem kurzen
CHAR(2)
in eine Referenz- oder Nachschlagetabelle normalisiert werden PS:O Open C Closed U [NotKnown]
-
Die Datenwerte {
Open;Closed;etc
} werden nicht mehr in Millionen von Zeilen dupliziert. Außerdem spart es Platz. -
Der zweite Punkt ist die einfache Änderung, wenn
Closed
wurden inExpired
geändert , muss wieder eine Zeile geändert werden, und das spiegelt sich in der gesamten Datenbank wider; wohingegen in den nicht normalisierten Dateien Millionen von Zeilen geändert werden müssen. -
Hinzufügen neuer Datenwerte , z.B. (
H,HalfOpen
) ist dann einfach eine Frage des Einfügens einer Zeile.
-
-
in Offene Architektur Begrifflich ist die Nachschlagetabelle eine gewöhnliche Tabelle. Es existiert im [SQL-konformen] Katalog; solange der
FOREIGN KEY
Relation definiert wurde, kann das Berichtstool auch diese finden. -
ENUM
ein Non-SQL ist, verwenden Sie es nicht. In SQL ist "enum" eine Lookup-Tabelle. -
Der nächste Punkt betrifft die Aussagekraft des Schlüssels.
- Wenn der Schlüssel für den Benutzer bedeutungslos ist, gut, verwenden Sie ein {
INT;BIGINT;GUID;etc
} oder was auch immer geeignet ist; nummerieren Sie sie nicht inkrementell; "Lücken" zulassen. - Aber wenn der Schlüssel für den Benutzer aussagekräftig ist, verwenden Sie keine bedeutungslose Zahl, sondern einen aussagekräftigen relationalen Schlüssel.
- Wenn der Schlüssel für den Benutzer bedeutungslos ist, gut, verwenden Sie ein {
-
Jetzt werden einige Leute in Bezug auf die Beständigkeit von PKs auf Tangenten eingehen. Das ist ein separater Punkt. Ja, natürlich, verwenden Sie immer einen stabilen Wert für einen PK (nicht "unveränderlich", weil so etwas nicht existiert und ein vom System generierter Schlüssel keine Zeileneindeutigkeit bietet).
-
{
M,F
} werden sich wahrscheinlich nicht ändern -
wenn Sie {
0,1,2,4,6
verwendet haben }, nun ändern Sie es nicht, warum sollten Sie das wollen. Diese Werte sollten bedeutungslos sein, denken Sie daran, nur ein sinnvoller Schlüssel muss geändert werden. -
Wenn Sie aussagekräftige Schlüssel verwenden, verwenden Sie kurze alphabetische Codes, die Entwickler leicht verstehen (und daraus die lange Beschreibung ableiten können). Sie werden dies nur zu schätzen wissen, wenn Sie
SELECT
codieren und stellen Sie fest, dass Sie nichtJOIN
müssen jede Nachschlagetabelle. Auch Power-User wissen das zu schätzen.
-
-
Da PKs stabil sind, insbesondere in Nachschlagetabellen, können Sie sicher codieren:
WHERE status_code = 'O' -- Open
Das müssen Sie nicht
JOIN
die Nachschlagetabelle und erhalten Sie die DatenwertOpen
, als Entwickler sollten Sie wissen, was die Lookup PKs bedeuten.
Zu guter Letzt, wenn die Datenbank groß wäre und BI-, DSS- oder OLAP-Funktionen zusätzlich zu OLTP unterstützte (so wie ordnungsgemäß normalisierte Datenbanken dies können), dann ist die Nachschlagetabelle tatsächlich eine Dimension oder ein Vektor in Dimension-Fact Analysen. Wenn es nicht vorhanden wäre, müsste es hinzugefügt werden, um die Anforderungen dieser Software zu erfüllen, bevor solche Analysen montiert werden können.
- Wenn Sie dies von Anfang an für Ihre Datenbank tun, müssen Sie sie (und den Code) später nicht aktualisieren.
Ihr Beispiel
SQL ist eine Low-Level-Sprache und daher umständlich, insbesondere wenn es um JOINs
geht . Das ist es, was wir haben, also müssen wir die Belastung einfach akzeptieren und damit umgehen. Dein Beispielcode ist in Ordnung. Aber einfachere Formulare können dasselbe tun.
Ein Berichtstool würde Folgendes generieren:
SELECT p.*,
s.name
FROM posts p,
status s
WHERE p.status_id = s.status_id
AND p.status_id = 'O'
Ein weiteres Beispiel
Für Bankensysteme, in denen wir aussagekräftige Kurzcodes verwenden (da sie aussagekräftig sind, ändern wir sie nicht mit den Jahreszeiten, wir ergänzen sie nur), vorausgesetzt, eine Nachschlagetabelle wie (sorgfältig ausgewählt, ähnlich wie ISO-Ländercodes) :Eq Equity
EqCS Equity/Common Share
OTC OverTheCounter
OF OTC/Future
Code wie dieser ist üblich:
WHERE InstrumentTypeCode LIKE "Eq%"
Und die Benutzer der GUI würden den Wert aus einem Dropdown-Menü auswählen, das
{Equity/Common Share;Over The Counter
anzeigt },
nicht {Eq;OTC;OF
}, nicht {M;F;U
}.
Ohne Nachschlagetabelle geht das nicht, weder in den Apps noch im Berichtstool.