ENUM
类型
ENUM
是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举。
在下列某些情况下,值也可以是空串(""
) 或 NULL
:
- 如果将一个无效值插入一个
ENUM
(即,一个不在允许值列表中的字符串),空字符串将作为一个特殊的错误值被插入。事实上,这个字符串有别于一个"普通的"空字符串,因为这个字符串有个数字索引值为 0。稍后有更详细描述。 - 如果一个
ENUM
被声明为NULL
,NULL
也是该列的一个合法值,并且该列的缺省值也将为NULL
。如果一个ENUM
被声明为NOT NULL
,该列的缺省值将是该列表所允许值的第一个成员。
每个枚举值均有一个索引值:
- 在列说明中列表值所允许的成员值被从 1 开始编号。
- 空字符串错误值的索引值为 0。这就意味着,你可以使用下面所示的
SELECT
语句找出被赋于无效ENUM
值的记录行。mysql> SELECT * FROM tbl_name WHERE enum_col=0;
NULL
值的索引值为NULL
。
例如,指定为 ENUM("one", "two", "three")
的一个列,可以有下面所显示的任一值。每个值的索引值也如下所示:
值 | 索引值 |
NULL | NULL |
"" | 0 |
"one" | 1 |
"two" | 2 |
"three" | 3 |
换个枚举最大可以有 65535 个成员值。
从 MySQL 3.23.51 开始,当表被创建时,ENUM
值尾部的空格将会自动删除。
当为一个 ENUM
列赋值时,字母的大小写是无关紧要的。然而,以后从列中检索出来的值的大小写却是匹配于创建表时所指定的允许值。
如果在一个数字语境中检索一个ENUM
,列值的索引值将被返回。例如,你可以像这样使用数字值检索一个 ENUM
列:
mysql> SELECT enum_col+0 FROM tbl_name;
如果将一个数字存储到一个 ENUM
中,数字被当作为一个索引值,并且存储的值是该索引值所对应的枚举成员。(但是,这在 LOAD DATA
将不能工作,因为它视所有的输入均为字符串。) 在一个 ENUM
字符串中存储数字是不明智的,因为它可能会打乱思维。
ENUM
值依照列规格说明中的列表顺序进行排序。(换句话说,ENUM
值依照它们的索引号排序。)举例来说,对于 ENUM("a", "b")
"a"
排在 "b"
后,但是对于 ENUM("b", "a")
, "b"
却排在 "a"
之前。空字符串排在非空字符串前,NULL
值排在其它所有的枚举值前。为了防止意想不到的结果,建议依照字母的顺序定义 ENUM
列表。也可以通过使用 GROUP BY CONCAT(col)
来确定该以字母顺序排序而不是以索引值。
如果希望得到一个 ENUM
列的所有可能值,可以使用 SHOW COLUMNS FROM table_name LIKE enum_colum
链接:http://www.cnblogs.com/skillCoding/archive/2012/03/14/2395404.html
这两天有趣的事情非常多,比如,所谓的QQ一些内部培训资料流出,网上各大网盘啥的流量一下子就非常高了。我当然也不小心就下载了一份,还没有看,不过好象什么百度的资料上已经有在线看了。因为自己也没有看,所以也不太清楚这玩意是真是假。
OK,上正文,16日的MYSQL专场,对于mysql优化讲的较详细的应该算是杨涛涛,他对MYSQL的一些字段类型进行了些介绍,包括他们所含 的字节长度,来介绍给我们让我们了解如何对数据库进行优化,比如,尽量不要用bigint,因为,这在项目中几乎不可能会被用上而他们占的字节长度却是在int中最长的,在数据量大的时候,既占空间,又影响速度。
还介绍了datetime和timstamp等的区别(更多可以看我以前写的连载,里面也有介绍)
不过,他唯独没有提起ENUM字段,说起这个ENUM,它倒是mysql的一个特色字段,在以前很多人喜欢用它,因为他可以设置字段的区间范围,会让值可以被数据库所控制,不至于出现意料不到的值(比如,字段只想有0和1,结果出现了2,那2就是赃数据了)
但ENUM带来的问题也不少,比如数据迁移的时候,他几乎不可能被其他数据库所支持,如果enum里面是字符串,对于其他数据库来说就更郁闷了,还不能设为tinyint等类型的字段(enum虽然可以存储字符串,但对于内部来说,还是以顺序进行索引,比如'a','b','c',我们也可以用索引值来获取值select * from tbl_name whre enum = 2,这与select * from tbl_name where enum = 'b'等义)如果你看明白了这两句SQL为什么等义,那么你也就可以了解为什么不主张用enum字段了。
因为,如果一个设计不合理的ENUM字段,给程序员带来的就完全是梦魇了,比如一个enum字段的范围是('0','1','2','3','4','5'),我想这时候,你会不会哭呢?要知道enum的枚举值对应的索引是从1开始的,因此,insert into table (enum)values(1),你知道是插的什么值吗?你select from table一下,你就会发现,你插入的并不是1,而是0。
更有甚者,由于enum的区间也是可以变动的,如果你在enum的枚举字段范围中加一个值,并且不是加在最后,那么也就相当于,你把原来的范围都改变了索引值,试想这又是多么一个恐怖的事情?
因此,如果你的系统中真的已经使用了mysql的enum字段类型,请在查询的时候直接查询值(并加上单引号),这样就不会使用enum自身隐藏的索引值来获取结果了。【顺便说一下,enum的默认索引是从NULL开始,如果你允许NULL并default NULL】
之所以提起这个,是在用shopnc系统的时候发现大量这样的字段,让人非常郁闷,几乎没有办法优化(如果是纯数值型,还是建议采用tinyint字段吧,毕竟它也只占一个字节,即使出现赃数据,也可以被接受,不象enum,如果纯数字型范围,更改了索引,你就不知道你查询的值是否正确了)
因此建议,如果字段是字符串,并且长度固定,可以尝试用char,如果是数值型,还是用tinyint吧,比较安全稳定,而且即使迁移,问题也不大。