SET
是一个字符串对象,可以包含零个或多个值,每个值必须从创建表时指定的允许值列表中选择。由多个集合成员组成的 SET
列值使用逗号 (,
) 分隔成员指定。由此产生的一个结果是,SET
成员值本身不应包含逗号。
例如,指定为 SET('one', 'two') NOT NULL
的列可以具有以下任何值
''
'one'
'two'
'one,two'
一个 SET
列最多可以包含 64 个不同的成员。
定义中的重复值会导致警告,或者如果启用了严格 SQL 模式,则会导致错误。
创建表时,表定义中的 SET
成员值的尾部空格将自动删除。
有关 SET
类型的语法和长度限制,请参见 第 13.3.1 节,“字符串数据类型语法”。
检索时,存储在 SET
列中的值将使用列定义中使用的字母大小写显示。请注意,SET
列可以分配字符集和排序规则。对于二进制或区分大小写的排序规则,在将值分配给列时,字母大小写将被考虑在内。
MySQL 以数字方式存储 SET
值,存储值的低位对应于第一个集合成员。如果您以数字上下文检索 SET
值,则检索到的值具有与组成列值的集合成员相对应的位。例如,您可以像这样从 SET
列中检索数值
mysql> SELECT set_col+0 FROM tbl_name;
如果将数字存储到 SET
列中,则数字的二进制表示形式中设置的位将确定列值中的集合成员。对于指定为 SET('a','b','c','d')
的列,成员具有以下十进制和二进制值。
SET 成员 |
十进制值 | 二进制值 |
---|---|---|
'a' |
1 |
0001 |
'b' |
2 |
0010 |
'c' |
4 |
0100 |
'd' |
8 |
1000 |
如果您将值 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
值排序在非 NULL
SET
值之前。
例如 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_col
包含 value
集合成员的行。第二个语句类似,但并不相同:它查找 set_col
任何地方包含 value
的行,即使作为另一个集合成员的子字符串也是如此。
以下语句也允许
mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
这些语句中的第一个语句查找包含第一个集合成员的值。第二个语句查找完全匹配。使用第二种类型的比较要小心。将集合值与 '
进行比较返回的结果与将值与 val1
,val2
''
进行比较的结果不同。您应该按照在列定义中列出的顺序指定值。val2
,val1
'
要确定 SET
列的所有可能值,请使用 SHOW COLUMNS FROM
并解析输出的 tbl_name
LIKE set_col
Type
列中的 SET
定义。
在 C API 中,SET
值作为字符串返回。有关使用结果集元数据来区分它们与其他字符串的信息,请参见 C API 基本数据结构。