TOC

MySQL set 类型

顾名思义,就是集合类型。

set('a', 'b', ...)

每个字段可以是指定选项中的若干个(包含 0 个)。

示例

CREATE TABLE `set_test` (
  `name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `val` set('a','b','c','d','e') COLLATE utf8mb4_general_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

insert set_test values('a', ('a,b'));
insert set_test values('b', ('a,c'));
select * from set_test;
-- +------+------+
-- | name | val  |
-- +------+------+
-- | a    | a,b  |
-- | b    | a,c  |
-- +------+------+
select name, val+0 from set_test;
-- +------+-------+
-- | name | val+0 |
-- +------+-------+
-- | a    |     3 |
-- | b    |     5 |
-- +------+-------+

长度

注意:因为逗号被用作切割不同的值,所以每个成员不能包含逗号。
注意:set 要求值的个数不能超过 64。
注意:Duplicate values in the definition cause a warning, or an error if strict SQL mode is enabled.

if 值的个数 <= 8:
    每个字段占用 1 个字节;
elif 值的个数 <= 16:
    每个字段占用 2 个字节;
elif 值的个数 <= 24:
    每个字段占用 3 个字节;
elif 值的个数 <= 32:
    每个字段占用 4 个字节;
elif 值的个数 <= 64:
    每个字段占用 8 个字节;
else:
    异常;

操作

  1. 数值计算,比如 sum, avg
  2. LIKE 就像逗号连接的字符串一样接受模式匹配。注意,如果搜索 %c% 能够匹配到包含 ccc 的行。
  3. FIND_IN_SET 查找指定值出现在 set 字段中的索引(从 1 开始)。
select name, val, find_in_set('c', val) from set_test where find_in_set('a', val) > 0;
-- +------+------+-----------------------+
-- | name | val  | find_in_set('c', val) |
-- +------+------+-----------------------+
-- | a    | a,b  |                     0 |
-- | b    | a,c  |                     3 |
-- +------+------+-----------------------+

参考资料与拓展阅读