### 11.3.6 SET 类型 [](<>)[](<>) 一种`放`是一个字符串对象,可以有零个或多个值,每个值都必须从创建表时指定的允许值列表中选择。`放`由多个集合成员组成的列值用逗号分隔的成员指定 (`,`)。这样做的结果是`放`成员值本身不应包含逗号。 例如,指定为的列`SET('一', '二') 非空`可以具有以下任何值: ``` '' 'one' 'two' 'one,two' ``` 一种[`放`](set.html)列最多可以有 64 个不同的成员。 如果启用了严格的 SQL 模式,定义中的重复值会导致警告或错误。 [](<>) 尾随空格会自动删除`放`创建表时表定义中的成员值。 看[字符串类型存储要求](storage-requirements.html#data-types-storage-reqs-strings)对于存储要求[`放`](set.html)类型。 看[第 11.3.1 节,“字符串数据类型语法”](string-type-syntax.html)为了[`放`](set.html)类型语法和长度限制。 检索时,存储在`放`列使用列定义中使用的字母大小写显示。注意`放`可以为列分配字符集和排序规则。对于二进制或区分大小写的排序规则,在为列分配值时会考虑字母大小写。 MySQL 存储`放`数值上的值,存储值的低位对应于第一个集合成员。如果你检索一个`放`在数值上下文中,检索到的值具有与构成列值的集合成员相对应的位集。例如,您可以从`放`像这样的列: ``` mysql> SELECT set_col+0 FROM tbl_name; ``` 如果一个数字被存储到一个`放`列,在数字的二进制表示中设置的位确定列值中的集合成员。对于指定为的列`SET('a','b','c','d')`,成员具有以下十进制和二进制值。 | `放`成员 | 十进制值 | 二进制值 | | ----- | ---- | ---- | | `'一种'` | `1` | `0001` | | `'b'` | `2` | `0010` | | `'c'` | `4` | `0100` | | `'d'` | `8` | `1000` | 如果您分配一个值`9`到这个专栏,也就是`1001`二进制,所以第一个和第四个`放`价值成员`'一种'`和`'d'`被选中,结果值为`'广告'`. 对于包含多个的值`放`元素,插入值时元素的列出顺序无关紧要。给定元素在值中列出多少次也无关紧要。稍后检索该值时,该值中的每个元素都会出现一次,并根据创建表时指定的顺序列出元素。假设一列被指定为`SET('a','b','c','d')`: ``` mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd')); ``` 如果您插入值`'广告'`,`'d,a'`, `'添加'`, `'a,d,a'`, 和`'爸爸'`: ``` 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 ``` 然后所有这些值显示为`'广告'`检索时: ``` mysql> SELECT col FROM myset; +------+ | col | +------+ | a,d | | a,d | | a,d | | a,d | | a,d | +------+ 5 rows in set (0.04 sec) ``` 如果你设置一个`放`列到不受支持的值,该值将被忽略并发出警告: ``` 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 模式,尝试插入无效`放`值导致错误。 `放`值按数字排序。`空值`值在非之前排序`空值` `放`价值观。 功能如[`和()`](aggregate-functions.html#function_sum)要么[`平均()`](aggregate-functions.html#function_avg)如果需要,期望数字参数将参数转换为数字。为了`放`值,强制转换操作导致使用数值。 通常,您搜索`放`值使用[`FIND_IN_SET()`](string-functions.html#function_find-in-set)函数或[`喜欢`](string-comparison-functions.html#operator_like)操作员: ``` 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`*包含*`价值`*集成员。第二个类似,但不一样:它找到行*`set_col`*包含*`价值`*任何地方,甚至作为另一个集合成员的子字符串。 也允许以下语句: ``` mysql> SELECT * FROM tbl_name WHERE set_col & 1; mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2'; ``` 这些语句中的第一个语句查找包含第一个集合成员的值。第二个寻找完全匹配。小心与第二种类型的比较。比较设定值`'*`val1`*,*`val2`*'`返回与比较值不同的结果`'*`val2`*,*`val1`*'`.您应该按照列定义中列出的相同顺序指定这些值。 确定所有可能的值`放`列,使用`显示来自 * 的列`tbl_name`* 喜欢 *`set_col`*`并解析`放`中的定义`类型`列的输出。 在 C API 中,`放`值作为字符串返回。有关使用结果集元数据将它们与其他字符串区分开来的信息,请参阅[C API 基本数据结构](https://dev.mysql.com/doc/c-api/8.0/en/c-api-data-structures.html).