为什么MySQL将1加到ENUM值?

时间:2013-06-27 21:19:19

标签: mysql performance enums

当我从ENUM字段尝试select sum时,我发现了一些奇怪的东西。它为这些值增加了1!我使用的样本表如下所示:

x     y
_______
3  |  2
0  |  1

x y 都是ENUM ('0','1','2','3')

我的查询如下:

select sum(x), sum(y), sum(x+y) from myfield

结果是:

5    5   10

这很奇怪。这是否意味着这种行为是否一致?我可以使用类似的东西:

select sum(x - 1), sum(y - 1), sum((x-1)+(y-1)) from myfield

会产生正确的结果,还是这种行为特别是我的数据库服务器特有的?

感谢。

修改 对于那些想知道我为什么使用ENUM的人来说,这是因为我使用的实际字段包含'AR',它不能放入tinyint

2 个答案:

答案 0 :(得分:3)

由于ENUM字段实际上只是INT UNSIGNED,如果对ENUM使用整数值,它将无法正常工作。例如,您ENUM的{​​{1}}内部存储为数字'0',而您的1则存储为数字'1'。令人惊讶的是,空字符串2在内部存储为''。这是一个不能按预期工作的例子:

0

条款mysql> CREATE TABLE enumtest ( -> id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, -> a ENUM ('0','1','2','3') NOT NULL DEFAULT '0', -> i int unsigned NOT NULL DEFAULT 0 -> ); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO enumtest SET a = 0, i=0; Query OK, 1 row affected, 1 warning (0.01 sec) mysql> SHOW WARNINGS; +---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1265 | Data truncated for column 'a' at row 1 | +---------+------+----------------------------------------+ 1 row in set (0.00 sec) mysql> INSERT INTO enumtest SET a = '0', i=0; Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO enumtest SET a = 1, i=1; Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO enumtest SET a = '1', i=1; Query OK, 1 row affected (0.00 sec) mysql> SELECT a,0+a,i FROM enumtest; +---+-----+---+ | a | 0+a | i | +---+-----+---+ | | 0 | 0 | | 0 | 1 | 0 | | 0 | 1 | 1 | | 1 | 2 | 1 | +---+-----+---+ 4 rows in set (0.00 sec) mysql> SELECT SUM(a),SUM(0+a), SUM(i) FROM enumtest; +--------+----------+--------+ | SUM(a) | SUM(0+a) | SUM(i) | +--------+----------+--------+ | 4 | 4 | 2 | +--------+----------+--------+ 1 row in set (0.00 sec) 强制0+a为其基础ENUM值。这相当于UNSIGNED

答案 1 :(得分:2)

这是因为在枚举列上执行SUM()并不会按照您的想法执行操作。为枚举列类型存储的数据是枚举的索引,索引从1开始,而这个索引是mysql将SUM()

显示时,您的表格如下所示:

x     y
_______
3  |  2
0  |  1

这显示了您的枚举值 - 您恰好将枚举值定义为数字。您可以将它们定义为例如ENUM ('blue','red','green','yellow') 它看起来像是:

x         y
_______________
yellow  |  green
blue    |  red

但是,这仅供显示。实际存储在该表的行中的是 枚举中的索引。

  

列规范中列出的元素被指定为索引   数字,从1开始。

因此,这些索引从1开始。这些基础数据是SUM()和其他聚合函数用于ENUM列。没有隐式转换为枚举值,您也将其定义为数字。

即。存储的数据是这些索引:

x     y
_______
4  |  3
1  |  2

虽然它对SUM枚举没有意义,但是当使用SUM()

时,mysql会汇总这些索引

必须阅读docs