11.3.6 SET 类型

官方文档地址:11.3.6 The SET Type


SET是一个有零个或多个值字符串对象,每个值都必须从创建表时指定的允许值列表中选择。由多个成员组成的SET列值用逗号(,)分隔。这样做的结果是,SET成员值本身不应该包含逗号。

例如,指定为SET('one', 'two') NOT NULL的列可以有以下任何一个值:

''
'one'
'two'
'one,two'

一个SET列最多可以有64个不同的成员。

如果启用了严格SQL模式,定义中的重复值将导致警告或错误。

创建表时,表定义中的SET成员值会自动删除尾随空格。

有关SET类型的存储要求,请参见 11.7 数据类型存储需求

关于SET类型语法和长度限制,请参见 11.3.1 字符串数据类型语法

检索时,存储在SET列中的值将使用列定义中使用的字母来显示。注意,可以为SET列分配一个字符集和排序规则。对于二进制或区分大小写的排序规则,在为列赋值时要考虑字母。

MySQL 以数字方式存储SET值,存储值的低序位对应于第一个SET成员。如果在数字上下文中检索一个SET值,则检索的值具有与组成列值的集合成员对应的位集。例如,你可以像这样从SET列中检索数值:

mysql> SELECT set_col+0 FROM tbl_name;

如果一个数字存储在一个SET列中,则以该数字的二进制表示形式设置的位将确定列值中的已设置成员。对于指定为SET('a','b','c','d')的列,成员有以下的十进制和二进制值。

SET 成员十进制值二进制值
‘a’10001
‘b’20010
‘c’40100
‘d’81000

如果您为这一列赋值9,即二进制的1001,那么第一个和第四个SET值成员'a''d'被选中,结果值是'a,d'

对于包含多个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)

如果启用了严格的 SQL 模式,尝试插入无效的SET值将导致错误。

SET值按数字排序。NULL值排序在非NULLSET值之前。

SUM()AVG()等需要数字参数的函数在必要时将参数转换为数字。对于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%';

第一个语句查找set_colSET成员包含'value'的行。第二个相似,但不相同:它查找set_col在任何地方包含'value'的行,即使是作为另一个SET成员的子字符串。

也允许使用以下语句:

mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

第一个语句查找包含第一个 set 成员的值。第二个是寻找精确的匹配。要小心第二种类型的比较。将设置的值与'val1,val2'进行比较和与'val2,val1'进行比较会返回不同的结果。您应该按照列定义中列出的顺序指定值。

要确定SET列的所有可能值,可以使用SHOW COLUMNS FROM tbl_name LIKE set_col,在输出的 Type 列可以看到SET的定义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值