epo*_*olf 18 enums database-design
如何在不支持枚举的数据库中实现枚举字段?(即SQLite)
需要使用" field=?" 轻松搜索字段 所以使用任何类型的数据序列化是一个坏主意.
Bil*_*win 54
使用外键到查找表是我使用的方法.实际上,即使我使用支持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)
);
Run Code Online (Sandbox Code Playgroud)
不可否认,存储字符串比MySQL的实现需要更多的空间ENUM,但除非有问题的表有数百万行,否则它几乎不重要.
查找表的其它优点是,你可以添加或删除列表中的值用一个简单的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'))
);
Run Code Online (Sandbox Code Playgroud)
但是这种CHECK约束的使用具有与以下相同的缺点ENUM:难以更改值列表ALTER TABLE,难以查询允许值列表,难以注释值.
PS:SQL中的等式比较运算符是单个=.双重==在SQL中没有意义.