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_colType 列中的 SET 定义。
在 C API 中,SET 值作为字符串返回。有关使用结果集元数据来区分它们与其他字符串的信息,请参见 C API 基本数据结构。