如何在数据库中处理没有枚举字段的枚举?

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,但除非有问题的表有数百万行,否则它几乎不重要.

查找表的其它优点是,你可以添加或删除列表中的值用一个简单的INSERTDELETE,而与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中没有意义.

  • 最佳答案,10年后,我的+1 (2认同)