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

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

''

'one'

'two'

'one,two'

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

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

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

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

MySQL以SET数字方式存储值,存储值的低位对应于第一个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值,强制转换操作将导致使用数值。

通常,您SET使用FIND_IN_SET()函数或 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包含 valueset成员的行 。第二个相似,但不相同:它查找set_col包含 value任何位置的行 ,甚至作为另一个set成员的子字符串。

也允许使用以下语句:

mysql>SELECT * FROM tbl_name WHERE set_col & 1;

mysql>SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

这些语句中的第一个语句查找包含第一个set成员的值。第二个寻找完全匹配。注意第二种类型的比较。比较设定值所 返回的结果不同于将数值与进行比较 。您应该按照列定义中列出的顺序指定值。 'val1,val2''val2,val1'

要确定SET 列的所有可能值,请使用并解析 输出列中的定义。 SHOW COLUMNS FROM tbl_name LIKE set_colSETType

在C API中,SET值以字符串形式返回。