文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  SET 类型

13.3.7 SET 类型

SET 是一个字符串对象,可以包含零个或多个值,每个值必须从创建表时指定的允许值列表中选择。由多个集合成员组成的 SET 列值使用逗号 (,) 分隔成员指定。由此产生的一个结果是,SET 成员值本身不应包含逗号。

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

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

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

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

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

有关 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 基本数据结构