文档首页
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 的列可以具有以下任何值

Press CTRL+C to copy
'' 'one' 'two' 'one,two'

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

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

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

有关 SET 类型的存储需求,请参见 字符串类型存储需求

有关 SET 类型的语法和长度限制,请参见 第 13.3.1 节,“字符串数据类型语法”

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

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

Press CTRL+C to copy
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')

Press CTRL+C to copy
mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));

如果您插入值 'a,d''d,a''a,d,d''a,d,a''d,a,d'

Press CTRL+C to copy
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'

Press CTRL+C to copy
mysql> SELECT col FROM myset; +------+ | col | +------+ | a,d | | a,d | | a,d | | a,d | | a,d | +------+ 5 rows in set (0.04 sec)

如果您将 SET 列设置为不支持的值,则该值将被忽略并发出警告

Press CTRL+C to copy
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

Press CTRL+C to copy
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 的行,即使作为另一个集合成员的子字符串也是如此。

以下语句也允许

Press CTRL+C to copy
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 基本数据结构