Использование внешнего ключа для справочной таблицы - это подход, который я использую. Фактически, я использую это, даже когда я использую базу данных, которая поддерживает ENUM (например, MySQL).
Для простоты я могу пропустить вездесущий "id
" для таблицы поиска и просто использовать фактическое значение, которое мне нужно в моей основной таблице, в качестве первичного ключа таблицы поиска. Таким образом, вам не нужно делать объединение, чтобы получить значение.
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)
);
По общему признанию, хранение строк занимает больше места, чем реализация ENUM
в MySQL, но если в рассматриваемой таблице миллионы строк, это вряд ли имеет значение.
Другие преимущества справочной таблицы заключаются в том, что вы можете добавлять или удалять значение из списка с помощью простого INSERT
или DELETE
, тогда как с ENUM
вы должны использовать ALTER TABLE
для переопределения списка.
Также попробуйте запросить текущий список разрешенных значений в ENUM
, например, чтобы заполнить список выбора в вашем пользовательском интерфейсе. Это большое раздражение! С таблицей поиска это легко: SELECT status from BugStatus
.
Также вы можете добавить другие столбцы атрибутов в таблицу поиска, если вам нужно (например, чтобы отметить варианты, доступные только администраторам). В ENUM
вы не можете комментировать записи; это просто простые значения.
Другой вариант, кроме таблицы поиска, заключается в использовании CHECK
ограничений (при условии, что база данных поддерживает их - MySQL нет):
CREATE TABLE Bugs (
bug_id SERIAL PRIMARY KEY,
summary VARCHAR(80),
...
status VARCHAR(20) NOT NULL
CHECK (status IN ('NEW', 'OPEN', 'FIXED'))
);
Но это использование ограничения CHECK
страдает теми же недостатками, что и ENUM
: трудно изменить список значений без ALTER TABLE
, сложно запросить список разрешенных значений, трудно аннотировать значения.
PS: оператор сравнения равенства в SQL является единственным =
. Двойной ==
не имеет значения в SQL.