如何处理数据库中没有枚举字段的枚举? [英] How to handle enumerations without enum fields in a database?

查看:28
本文介绍了如何处理数据库中没有枚举字段的枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在不支持枚举的数据库中实现枚举字段?(即 SQLite)

How would I implement a enumeration field in a database that doesn't support enumerations? (i.e. SQLite)

需要使用field = ?"轻松搜索字段所以使用任何类型的数据序列化都是一个坏主意.

The fields need to be easily searchable with "field = ?" so using any type of data serialization is a bad idea.

推荐答案

使用查找表的外键是我使用的方法.事实上,即使我使用支持 ENUM 的数据库(例如 MySQL),我也会使用它.

Using a foreign key to a lookup table is the approach I use. In fact, I use this even when I do use a database that supports ENUM (e.g. MySQL).

为简单起见,我可能会跳过查找表中一直存在的id",而仅使用主表中所需的实际值作为查找表的主键.这样你就不需要进行连接来获取值.

For simplicity, I may skip the ever-present "id" for the lookup table, and just use the actual value I need in my main table as the primary key of the lookup table. That way you don't need to do a join to get the value.

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)
);

诚然,存储字符串比 MySQL 的 ENUM 实现需要更多的空间,但除非有问题的表有数百万行,否则这无关紧要.

Admittedly, storing strings takes more space than MySQL's implementation of ENUM, but unless the table in question has millions of rows, it hardly matters.

查找表的其他优点是您可以使用简单的 INSERTDELETE 从列表中添加或删除值,而使用 ENUM 你必须使用 ALTER TABLE 来重新定义列表.

Other advantages of the lookup table are that you can add or remove a value from the list with a simple INSERT or DELETE, whereas with ENUM you have to use ALTER TABLE to redefine the list.

还尝试在 ENUM 中查询当前的允许值列表,例如在您的用户界面中填充一个选择列表.这是一个主要的烦恼!使用查找表,很容易:SELECT status from BugStatus.

Also try querying the current list of permitted values in an ENUM, for instance to populate a pick-list in your user interface. It's a major annoyance! With a lookup table, it's easy: SELECT status from BugStatus.

如果需要,您还可以将其他属性列添加到查找表中(例如,标记仅供管理员使用的选项).在 ENUM 中,您不能对条目进行注释;它们只是简单的值.

Also you can add other attribute columns to the lookup table if you need to (e.g. to mark choices available only to administrators). In an ENUM, you can't annotate the entries; they're just simple values.

除了查找表之外的另一个选项是使用 CHECK 约束(前提是数据库支持它们——MySQL 直到 8.0.16 版本才支持 CHECK):

Another option besides a lookup table would be to use CHECK constraints (provided the database supports them -- MySQL doesn't support CHECK until version 8.0.16):

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 很难更改值列表,难以查询允许值列表,难以注释值.

But this use of a CHECK constraint suffers from the same disadvantages as the ENUM: hard to change the list of values without ALTER TABLE, hard to query the list of permitted values, hard to annotate values.

PS:SQL 中的相等比较运算符是单个 =.双 == 在 SQL 中没有意义.

PS: the equality comparison operator in SQL is a single =. The double == has no meaning in SQL.

这篇关于如何处理数据库中没有枚举字段的枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆