代码之家  ›  专栏  ›  技术社区  ›  epochwolf

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

  •  18
  • epochwolf  · 技术社区  · 17 年前

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

    字段需要易于搜索“ field =?”因此,使用任何类型的数据序列化都是一个坏主意。

    5 回复  |  直到 14 年前
        1
  •  53
  •   Bill Karwin    17 年前

    使用外键 查找表 是我使用的方法。事实上,即使使用了支持枚举的数据库(例如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)
    );
    

    不可否认,存储字符串比MySQL实现 ENUM 但是,除非所讨论的表有数百万行,否则它几乎不重要。

    查阅表格的其他优点是,您可以使用简单的 INSERT DELETE 反之 枚举 你必须使用 ALTER TABLE 重新定义列表。

    还可以尝试查询 枚举 例如,在用户界面中填充一个选择列表。这是个大麻烦!使用查阅表格,很容易: SELECT status from BugStatus .

    如果需要,还可以将其他属性列添加到查阅表格中(例如,标记仅对管理员可用的选项)。在一个 枚举 ,您不能注释条目;它们只是简单的值。

    除了查找表之外的另一个选项是使用 CHECK 约束条件 (如果数据库支持它们——MySQL不支持):

    CREATE TABLE Bugs (
      bug_id            SERIAL PRIMARY KEY,
      summary           VARCHAR(80),
      ...
      status            VARCHAR(20) NOT NULL
        CHECK (status IN ('NEW', 'OPEN', 'FIXED'))
    );
    

    但这种用法 检查 约束与 枚举 :很难更改值列表 变更表 ,很难查询允许值的列表,很难注释值。

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

        2
  •  2
  •   Chris Nava    17 年前

    为了限制可能的值,我将使用外键来保存枚举项的表。

    如果不想加入以进行搜索,则将键设为varchar;如果加入不是问题,则将键设为int,除非需要搜索该字段,否则不要加入。

    注意,将枚举放在数据库中会妨碍对代码中的值进行编译时检查(除非您在代码中复制了枚举)。我发现这是一个很大的缺点。

        3
  •  1
  •   Brann    17 年前

    你基本上有两个选择:

    • 使用整数字段

    • 使用varchar字段

    我个人主张使用varchars,因为如果更改枚举+字段是人类可读的,则不会破坏任何内容,但是ints也有一些优点,即性能(数据的大小是一个明显的例子)。

        4
  •  0
  •   RN.    17 年前

    这是我最近做的

    在我的hibernate mapped pojo中,我将成员的类型保存为字符串,它在数据库中是varchar。

    此的setter采用枚举 还有另一个setter接受字符串——但这是私有的(或者您可以直接映射字段——如果您喜欢的话)。

    现在,我使用的字符串是从所有字符串中封装出来的。对于应用程序的其余部分,我的域对象使用枚举。 至于数据库,我使用的是字符串。

    如果我错过了你的问题-我道歉。

        5
  •  -1
  •   Hans Lawrenz    17 年前

    我会用varchar。这不是你的选择吗?