有时我不确定在MysQL中是否使用enum或char(1)。例如,我存储帖子的状态。通常,我只需要Active
字段中的 Passive
或 status
值。我有两个选择:
// CHAR
status char(1);
// ENUM (but too limited)
status enum('A', 'P');
如果我想在将来再添加一种状态类型(即Hidden
)怎么办?如果我有小数据,这将不是问题。但是如果我的数据太大,那么编辑ENUM类型就会出问题。我想。
如果我们还考虑MySQL性能,那么您的建议是什么?我会走哪条路?
答案 0 :(得分:6)
都不是。您通常将tinyint与查找表一起使用
char(1)会稍慢,因为比较使用collation
混淆:当你扩展到超过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'
您甚至可以使用LIKE
和FIND_IN_SET
运算符来执行更有用的查询。
阅读MySQL文档以获取更多信息;
http://dev.mysql.com/doc/refman/5.1/en/set.html
希望它有所帮助!
戴夫
答案 3 :(得分:0)
很难说不知道你的状态的语义,但对我来说“隐藏”似乎不是“主动”或“被动”的替代品,即你可能想要同时拥有“主动隐藏”和“被动”隐”;这会随着每个新的非独占“状态”而退化,最好用布尔标志来实现你的模式:一个用于主动/被动区分,一个用于隐藏/可见区分。当条件为“WHERE NOT hidden”或“WHERE active”时,查询变得更易读,而不是“WHERE status ='A'”。