MySQL中的枚举或char(1)

时间:2011-11-07 15:04:03

标签: mysql performance

有时我不确定在MysQL中是否使用enum或char(1)。例如,我存储帖子的状态。通常,我只需要Active字段中的 Passive status 值。我有两个选择:

// CHAR
status char(1);

// ENUM (but too limited)
status enum('A', 'P');

如果我想在将来再添加一种状态类型(即Hidden)怎么办?如果我有小数据,这将不是问题。但是如果我的数据太大,那么编辑ENUM类型就会出问题。我想。

如果我们还考虑MySQL性能,那么您的建议是什么?我会走哪条路?

4 个答案:

答案 0 :(得分:6)

都不是。您通常将tinyint与查找表一起使用

  • char(1)会稍慢,因为比较使用collat​​ion

  • 混淆:当你扩展到超过A和P

  • 使用字母会在添加更多类型时限制您。见最后一点。

  • 我见过的每个系统都有多个客户端,例如报告。 A和P必须在每个客户端代码中解析为Active和Passive

  • 可扩展性:再添加一个类型(“S”表示“已暂停”),您可以将一行添加到查找表中或更改大量代码和约束。还有你的客户代码

  • 维护:逻辑分为3个位置:数据库约束,数据库代码和客户端代码。使用查找和外键,它可以在一个地方

  • 枚举不可携带

使用单个字母或Enum

的正面

注意:有一个相关的DBA.SE MySQL question about Enums。建议也在那里使用查找表。

答案 1 :(得分:1)

您可以使用

status enum('Active', 'Passive');

它不会在行中保存字符串,它只会在表结构中保存一个引用enum成员的数字,因此大小相同但比char(1)或{{{{{{{{ 1}}。
无论您的数据有多大,编辑枚举都不是问题

答案 2 :(得分:1)

我会为此使用二进制SET字段,但没有在数据库中专门标记选项。所有“标签”都将在您的代码中完成,但它确实提供了一些非常灵活的选项。

例如,您可以创建一个包含八个“选项”的SET,例如;

`column_name` SET('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') NOT NULL DEFAULT ''

在您的应用程序中,您可以将'a'定义为表示“活动”或“被动”,“b”可以表示“隐藏”,其余部分可以保留未定义,直到您需要它们为止。

然后,您可以在该字段上使用各种有用的二进制操作,例如,您可以通过运行提取所有“隐藏”的操作;

WHERE `column_name` & 'b'

所有那些通过跑步“活跃”和“隐藏”的人;

WHERE `column_name` & 'a' AND `column_name` & 'b'

您甚至可以使用LIKEFIND_IN_SET运算符来执行更有用的查询。

阅读MySQL文档以获取更多信息;

http://dev.mysql.com/doc/refman/5.1/en/set.html

希望它有所帮助!

戴夫

答案 3 :(得分:0)

很难说不知道你的状态的语义,但对我来说“隐藏”似乎不是“主动”或“被动”的替代品,即你可能想要同时拥有“主动隐藏”和“被动”隐”;这会随着每个新的非独占“状态”而退化,最好用布尔标志来实现你的模式:一个用于主动/被动区分,一个用于隐藏/可见区分。当条件为“WHERE NOT hidden”或“WHERE active”时,查询变得更易读,而不是“WHERE status ='A'”。