6

所以几年前,我看到了一个由第 3 方开发的系统的 DB 模式,并注意到他们使用 enum('y','n') 而不是布尔(tinyint)字段。我不知道为什么,但我非常喜欢它,我发现它使事情更容易阅读(我知道这完全是主观的),但我采用了它并从那时起开始使用它。我想我可以把它换成“真”和“假”,但是,我能说什么,我只是喜欢它。

话虽如此,以这种方式做事是否有任何挫折——除了可能会有点烦人在游戏中迟到的程序员?

4

3 回答 3

10

是的,这很糟糕。你失去了直观的布尔逻辑(SELECT * FROM user WHERE NOT banned变成SELECT * FROM user WHERE banned = 'n'),并且你在应用程序端接收字符串而不是布尔值,所以你的布尔条件也变得很麻烦。其他使用您的架构的人会因为看到类似标志的列名并尝试在它们上使用布尔逻辑而被咬伤。

于 2012-06-04T13:52:59.837 回答
1

手册中所述

如果将无效值插入到ENUM(即,允许值列表中不存在的字符串)中,则会将空字符串作为特殊错误值插入。该字符串与“普通”空字符串的区别在于该字符串的数值为 0。有关枚举的数字索引的详细信息,请参阅第 11.4.4 节,“枚举文字的索引值”</a>价值观。

如果启用了严格的 SQL 模式,则尝试插入无效ENUM值会导致错误。

在这方面,一个ENUM导致与一个BOOLEAN类型不同的行为;否则我倾向于同意@lanzz 的回答,即它使与应用程序的集成变得不那么直接。

于 2012-06-04T13:58:54.610 回答
0

要考虑的一个因素是编写原始模式的人是否将其限制为 MySQL。如果它只打算在 MySQL 上运行,那么适应 MySQL 是有意义的。如果相同的模式旨在与其他 DBMS 一起使用,那么适用于所有相关 DBMS 的更通用的模式设计对于设计人员可能会更好。

话虽如此,这enum是适度特定于 MySQL 的,但enum可以在其他 DBMS 中轻松创建等效的东西:

CREATE TABLE ...
(
    ...
    FlagColumn   CHAR(1) NOT NULL CHECK(FlagColumn IN ('y', 'n')),
    ...
);

尽管有 SQL 标准,但不同 DBMS 处理 BOOLEAN 的方式并不像您希望的那样统一(原因是一如既往的历史;在标准之前,不太符合标准的系统对 BOOLEAN 的主题有变化,并且更改其实现会破坏其现有客户的代码)。

所以,我不会自动谴责使用enumover boolean,但最好使用boolean布尔标志。

于 2012-06-04T14:51:29.980 回答