Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  The SET Type

13.3.6 集合类型

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

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

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

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

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

在创建表时,SET 成员值的尾随空格将被自动删除。

请参阅 字符串类型存储要求,了解 SET 类型的存储要求。

请参阅 第 13.3.1 节,“字符串数据类型语法”,了解 SET 类型的语法和长度限制。

当检索时,存储在 SET 列中的值将使用在列定义中使用的字母大小写。注意,SET 列可以分配字符集和排序规则。对于二进制或大小写敏感的排序规则,字母大小写将在分配值时被考虑。

MySQL 以数字形式存储 SET 值,低位对应第一个集合成员。如果您在数字上下文中检索 SET 值,则检索到的值将具有对应于集合成员的位设置。例如,您可以像这样检索数字值:

mysql> SELECT set_col+0 FROM tbl_name;

如果将数字存储到 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 分配给该列,即二进制表示形式为 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的行,甚至是另一个集合成员的子字符串。

以下语句也是允许的:

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列中的集合定义。

在 C API 中,SET值作为字符串返回。有关使用结果集元数据来区分它们与其他字符串的信息,请参阅C API 基本数据结构