我刚在我的一张桌子上跑了一个“PROCEDURE ANALYZE()”。我有这个类型为INT的列,它只包含0到12之间的值(类别ID)。 MySQL说我会更好用ENUM('0','1','2',......,'12')。这个类别基本上是静态的,将来不会改变,但如果他们这样做,我可以改变该列并将其添加到ENUM列表中......
那么为什么ENUM在这种情况下更好?
编辑:我最感兴趣的是......的性能方面......
答案 0 :(得分:29)
简单地说,这是因为它以不同的方式编入索引。
在这种情况下,ENUM
说“这是这13个值中的一个”,而INT
说“它可能是任何整数。”
这意味着索引更容易,因为它不必考虑您不使用“以防万一”的那些整数的索引。
这与算法有关。
我感兴趣的是,当它到达INT
比ENUM
更快的时候。
使用ENUM
中的数字可能有点危险......就好像你将这个数字不加引号发送给SQL一样 - 你最终可能会得到错误的值!
答案 1 :(得分:20)
糟糕!在ENUM
字段中使用数字有很多含糊之处。小心。我记得的一个问题是你可以通过索引访问ENUMS
中的值:如果你的枚举是ENUM('A', 'B', 'C', '1', '2, '3')
,那么这两个查询是非常不同的:
INSERT INTO TABLE (example_col) VALUES( '1' ); -- example_col == 1
INSERT INTO TABLE (example_col) VALUES( 1 ); -- example_col == A
我假设推荐是因为它限制了可以进入表格的有效值。例如,插入13应该是默认选择。
更好的选择是使用TINYINT
代替INT
。 UNSIGNED TINYINT
的范围为0到255,只需1 byte to store。 INT
需要4个字节来存储。如果您想限制进入表格的值,可以添加检查值的ON INSERT
和ON UPDATE
触发器。
如果您担心ENUM
和TINYINT
之间的效果差异,您可以随时进行基准测试以了解不同之处。 This article似乎有点相关。
答案 2 :(得分:3)
因为它对可能的值引入了约束。
答案 3 :(得分:2)
我不是MySQL专家,但我的猜测是整数总是占用四个字节的空间,其中枚举根据所需的数据范围占用不同的空间。由于您只需要13个项目,因此您的列可能会使用1个字节。
答案 4 :(得分:1)
在Oracle上,我会有一个BITMAP索引,它比基于哈希的查找要快得多。 (所以我认为MySQL的查询验证或索引有类似的好处。)
有趣的是,MySQL文档建议使用“看起来像数字的东西”对于ENUM类型来说是一个糟糕的选择,因为枚举值和枚举索引(http://dev.mysql.com/doc/refman/5.0/en/enum.html)之间可能存在混淆。