MYSQL中 ENUM 类型
2015-10-28 23:57
471 查看
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 |
从 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。
SET类型
SET是一个字符串对象,可以有零或多个值,其值来自表创建时规定的允许的一列值。指定包括多个SET成员的SET列值时各成员之间用逗号(‘,’)间隔开。这样SET成员值本身不能包含逗号。例如,指定为SET('one', 'two') NOT NULL的列可以有下面的任何值:
''
'one'
'two'
'one,two'
SET最多可以有64个不同的成员。
当创建表时,SET成员值的尾部空格将自动被删除。
当检索时,保存在SET列的值使用列定义中所使用的大小写来显示。请注意可以为SET列分配字符集和 校对规则。对于二进制或大小写敏感的校对规则,当为列分配值时应考虑大小写。
MySQL用数字保存SET值,所保存值的低阶位对应第1个SET成员。如果在数值上下文中检索一个SET值,检索的值的位设置对应组成列值的SET成员。例如,你可以这样从一个SET列检索数值值:
mysql> SELECT set_col+0 FROM tbl_name;
如果将一个数字保存到SET列中,数字中二进制表示中的位确定了列值中的SET成员。对于指定为SET('a','b','c','d')的列,成员有下面的十进制和二进制值:
SET成员 | 十进制值 | 二进制值 |
'a' | 1 | 0001 |
'b' | 2 | 0010 |
'c' | 4 | 0100 |
'd' | 8 | 1000 |
对于包含多个SET元素的值,当插入值时元素所列的顺序并不重要。在值中一个给定的元素列了多少次也不重要。当以后检索该值时,值中的每个元素出现一次,根据表创建时指定的顺序列出元素。例如,假定某个列指定为SET('a','b','c','d'):
mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
插入值'a,d'、'd,a'、'a,d,d'、'a,d,a'和'd,a,d':
mysql> INSERT INTO myset (col) VALUES
-> ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
当检索时所有这些值显示为 'a,d':
mysql> SELECT col FROM myset;
+------+
| col |
+------+
| a,d |
| a,d |
| a,d |
| a,d |
| a,d |
+------+
5 rows in set (0.04 sec)
如果将SET列设置为一个不支持的值,则该值被忽略并发出警告:
mysql> INSERT INTO myset (col) VALUES ('a,d,d,s');
Query OK, 1 row affected, 1 warning (0.03 sec)
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'col' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.04 sec)
mysql> SELECT col FROM myset;
+------+
| col |
+------+
| a,d |
| a,d |
| a,d |
| a,d |
| a,d |
| a,d |
+------+
6 rows in set (0.01 sec)
SET值按数字顺序排序。NULL值排在非NULL SET值的前面。
通常情况,可以使用FIND_IN_SET()函数或LIKE操作符搜索SET值:
mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
第1个语句找出SET_col包含value set成员的行。第2个类似,但有所不同:它在其它地方找出set_col包含value的行,甚至是在另一个SET成员的子字符串中。
下面的语句也是合法的:
mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
第1个语句寻找包含第1个set成员的值。第2个语句寻找一个确切匹配的值。应注意第2类的比较。将set值与'val1,val2'比较返回的结果与同'val2,val1'比较返回的结果不同。指定值时的顺序应与在列定义中所列的顺序相同。
如果想要为SET列确定所有可能的值,使用SHOW COLUMNS FROM tbl_name LIKE set_col并解析输出中第2列的SET定义。
刚才研究MySQL文档,发现SET类型的真正含义:
实际上,SET可以包含最多64个成员,其值为一个整数。这个整数
的二进制码表示该SET的值的哪些成员为真。例如有SET('a','b','c','d'),
那么当它们的值为:
SET member Decimal value Binary value
-----------------------------
a 1 0001
b 2 0010
c 4 0100
d 8 1000
如果你将9存入某个SET域,那么其二进制值为1001,也就是说这
个值中'a'和'd'为真。
可以想到,如果这样的话,大家可以用LIKE命令和FIND_IN_SET()
函数来检索SET值:
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
当然,以下SQL语句也是合法的,他们显得更加简洁:
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
mysql> SELECT * FROM tbl_name WHERE set_col & 1;
哈哈,这么一来,大家下次控制权限的时候就不用设一个int型,然后
在那里与呀或的,还要另外定义权限的名称,用SET型字段轻松搞定!!
区别
mysql中的enum和set其实都是string类型的而且只能在指定的集合里取值, 不同的是set可以取多个值,enum只能取一个值。相关文章推荐
- mysql的order by与where加了索引与没有加索引的结果集区别
- MySQL数据备份之mysqldump使用
- Mysql group_concat
- MySQL不能启动 mysql-bin.index' not found (Errcode: 13)
- wamp数据库mysql解决中文乱码问题方法
- mysql 1449 : The user specified as a definer ('root'@'%') does not exist ,mysql 赋给用户权限 grant all privileges on
- 多种启动、停止、重启 MySQL 的方法
- MySQL 存储过程
- MySQL数据库INNODB 表损坏修复处理过程 无法repair的变通方法
- mysql ab 不同步的几种情况及解决方法
- MySQL优化器:index merge介绍
- mysql 用户管理和权限设置
- mysql数据库如何设置字符集
- 不停止MySQL服务增加从库的两种方式
- MySQL运行状态show status中文详解
- Mysql主主同步详细操作过程
- 使用mysql-proxy代理内网云服务器
- mysql 命令与高级用法
- MySQL多实例配置
- MySQL Cluster 7.4.8集群安装及遇到的问题