Mit einem Fremdschlüssel zu einer Lookup-Tabelle ist der Ansatz, den ich verwende. Tatsächlich benutze ich das sogar, wenn ich eine Datenbank verwende, die ENUM unterstützt (z. B. MySQL).
Der Einfachheit halber überspringe ich das immer vorhandene "id
" für die Nachschlagetabelle und verwende einfach den tatsächlichen Wert, den ich in meiner Haupttabelle benötige, als Primärschlüssel der Nachschlagetabelle. Auf diese Weise müssen Sie keinen Join durchführen, um den Wert zu erhalten.
CREATE TABLE BugStatus (
status VARCHAR(20) PRIMARY KEY
);
INSERT INTO BugStatus (status) VALUES ('NEW'), ('OPEN'), ('FIXED');
CREATE TABLE Bugs (
bug_id SERIAL PRIMARY KEY,
summary VARCHAR(80),
...
status VARCHAR(20) NOT NULL DEFAULT 'NEW',
FOREIGN KEY (status) REFERENCES BugStatus(status)
);
Zwar nimmt Strings speichert mehr Platz als MySQL-Implementierung von ENUM
, aber es sei denn, die betreffende Tabelle Millionen von Zeilen hat, es spielt kaum eine Rolle.
Weitere Vorteile der Lookup-Tabelle sind, dass Sie einen Wert aus der Liste mit einer einfachen INSERT
oder DELETE
hinzufügen oder entfernen können, während bei ENUM
Sie haben ALTER TABLE
zu verwenden, um die Liste neu zu definieren.
Versuchen Sie auch, die aktuelle Liste zulässiger Werte in einer ENUM
abzufragen, z. B. um eine Auswahlliste in Ihrer Benutzerschnittstelle zu füllen. Es ist ein großer Ärger! Mit einer Nachschlagetabelle ist es einfach: SELECT status from BugStatus
.
Sie können auch weitere Attributspalten zur Nachschlagetabelle hinzufügen, wenn dies erforderlich ist (z. B. zum Markieren von Auswahlmöglichkeiten, die nur für Administratoren verfügbar sind). In einem ENUM
können Sie die Einträge nicht kommentieren; Sie sind nur einfache Werte.
Eine weitere Option neben einer Lookup-Tabelle CHECK
Einschränkungen (vorausgesetzt, die Datenbank unterstützt sie - MySQL nicht der Fall ist) zu verwenden wäre:
CREATE TABLE Bugs (
bug_id SERIAL PRIMARY KEY,
summary VARCHAR(80),
...
status VARCHAR(20) NOT NULL
CHECK (status IN ('NEW', 'OPEN', 'FIXED'))
);
Aber diese Verwendung einer CHECK
Zwang leidet unter dem gleichen Nachteile wie die ENUM
: schwer zu ändern, die Liste der Werte ohne ALTER TABLE
, schwer die Liste der zulässigen Werte abzufragen, schwer zu kommentieren Werte.
PS: der Gleichheitsvergleichsoperator in SQL ist eine einzige =
. Die doppelte ==
hat keine Bedeutung in SQL.
Wenn dies ein Duplikat ist, bitte schön sein. Ich habe die Antwort auf StackOverflow gesucht, bevor ich gefragt habe. – epochwolf