108

对于“enum”和“set”的 MySQL 数据类型,使用一个与另一个有什么区别和优缺点?

示例数据类型:

  • 枚举('A','B','C')
  • 设置('A','B','C')

我知道的唯一区别是 ENUM 只允许选择一个值,而 SET 允许选择多个值。

4

7 回答 7

250

类比:
ENUM = 单选字段(仅接受的值是列出的值,只能选择一个)
SET = 复选框字段(仅接受的值是列出的值,可以选择多个)

于 2015-08-14T20:03:46.257 回答
75

As the MySQL documentation states:

Definition of a ENUM or SET column does act as a constraint on values entered into the column. An error occurs for values that do not satisfy these conditions:

An ENUM value must be one of those listed in the column definition, or the internal numeric equivalent thereof. The value cannot be the error value (that is, 0 or the empty string). For a column defined as ENUM('a','b','c'), values such as '', 'd', or 'ax' are illegal and are rejected.

A SET value must be the empty string or a value consisting only of the values listed in the column definition separated by commas. For a column defined as SET('a','b','c'), values such as 'd' or 'a,b,c,d' are illegal and are rejected.

于 2013-02-10T14:02:03.453 回答
48

Enum 和 Set 完全取决于要求,例如,如果您有一个单选按钮列表,一次只能选择一个,请使用 Enum。如果您有一个复选框列表,一次可以选择一个以上的项目,请使用 set。

于 2013-11-28T08:19:54.643 回答
25
CREATE TABLE setTest(
  attrib SET('bold','italic','underline')
);

INSERT INTO setTest (attrib) VALUES ('bold');
INSERT INTO setTest (attrib) VALUES ('bold,italic');
INSERT INTO setTest (attrib) VALUES ('bold,italic,underline');

你可以把上面的代码复制粘贴到mysql中,你会发现SET其实是一个集合。您可以存储您声明的每个属性组合。

CREATE TABLE enumTest(
 color ENUM('red','green','blue')
);

INSERT INTO enumTest (color) VALUES ('red');
INSERT INTO enumTest (color) VALUES ('gray');
INSERT INTO enumTest (color) VALUES ('red,green');

您也可以复制上面的代码。而且你会发现每个ENUM实际上每次只能存储一次。你会发现最后两行的结果都是空的。

于 2015-05-14T01:18:42.943 回答
11

其实很简单:

当您定义ENUM('Yes', 'No', 'Maybe')时,您必须仅插入这些值之一(或它们的位置索引号)

当您定义SET('R', 'W', 'X')时,您可以插入一个空字符串,或者这些值中的一个或多个。如果您插入不在预定义集中的内容,则会插入一个空字符串。请注意,在插入所有重复值之前,都会丢弃所有重复值,因此只插入每个允许值的一个实例。

希望这可以清除它。

请注意,Winbobob 的答案是不正确的,并且包含有缺陷的示例,因为插入多个值时,值必须是字符串,用逗号分隔。他所有的插入实际上只插入一个值(最后两个不在定义的集合中)

于 2018-08-22T05:40:08.247 回答
1

ENUM --> 只选择一个可用的值来插入。

(no_null, no_any_duplicate)


SET --> 选择任何组合或单个值,如集合并将它们插入。

(null, individual_values, all_the_available_values_together)

于 2021-01-06T14:36:46.113 回答
0

我补充了到目前为止答案中已经提到的几点,因为我在差异上添加了一个额外的点 -

MySQL 在内部将 ENUM 字符串值存储为值 1 到 n 的十进制整数,用于枚举中具有 n 个成员的列。

MySQL 将 SET 字符串值表示为一个位图,每个值使用一位,因此这些值在内部存储为 1、2、4、8、..... 最多 65,535 个,最多 64 个成员。

这一点证明如下——

枚举示例 -

我创建具有数据类型的table1列的表,具有以下表结构 -col1ENUM('a','b','c','d','e','f','g','h','i','j')

| table1 | CREATE TABLE `table1` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `col1` enum('a','b','c','d','e','f','g','h','i','j') DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

col1内部存储如下 -

+----+---------+---------------+
| id | element | decimal_value |
+----+---------+---------------+
|  1 | a       |             1 |
|  2 | b       |             2 |
|  3 | c       |             3 |
|  4 | d       |             4 |
|  5 | e       |             5 |
|  6 | f       |             6 |
|  7 | g       |             7 |
|  8 | h       |             8 |
|  9 | i       |             9 |
| 10 | j       |            10 |
+----+---------+---------------+

现在,假设我们要将值 -'e'插入col1

'e'有索引5

因此要进入'e'我们col1使用以下查询 -

INSERT INTO table1  VALUES (1, 5);

然后我们检查存在于table1-

SELECT * FROM table1;
+----+------+
| id | col1 |
+----+------+
|  1 | e    |
+----+------+

我们看到在第一行我们的值为col1as'e'

同样,假设我们想将值 -'i'插入col1

'i'有索引9

因此要进入'i'我们col1使用以下查询 -

INSERT INTO table1  VALUES (2, 9);

然后我们检查存在于table1-

SELECT * FROM table1;
+----+------+
| id | col1 |
+----+------+
|  1 | e    |
|  2 | i    |
+----+------+

我们看到在第二行我们的值为col1as'i'

同样,假设我们想将值 -'a'插入col1

'a'有索引1

因此要进入'a'我们col1使用以下查询 -

INSERT INTO table1  VALUES (3, 1);

然后我们检查存在于table1-

SELECT * FROM table1;
+----+------+
| id | col1 |
+----+------+
|  1 | e    |
|  2 | i    |
|  3 | a    |
+----+------+

我们看到在第三行我们的值为col1as'a'


设置示例 -

我创建具有数据类型的table1列的表,具有以下表结构 -col1SET('a','b','c','d','e','f','g','h','i','j')

| table1 | CREATE TABLE `table1` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `col1` set('a','b','c','d','e','f','g','h','i','j') DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

col1内部存储如下 -

+----+---------+----------------+---------------+
| id | element | binary_value   | decimal_value |
+----+---------+----------------+---------------+
|  1 | a       | 0000 0000 0001 |             1 |
|  2 | b       | 0000 0000 0010 |             2 |
|  3 | c       | 0000 0000 0100 |             4 |
|  4 | d       | 0000 0000 1000 |             8 |
|  5 | e       | 0000 0001 0000 |            16 |
|  6 | f       | 0000 0010 0000 |            32 |
|  7 | g       | 0000 0100 0000 |            64 |
|  8 | h       | 0000 1000 0000 |           128 |
|  9 | i       | 0001 0000 0000 |           256 |
| 10 | j       | 0010 0000 0000 |           512 |
+----+---------+----------------+---------------+

现在,假设我们要将值 -'e,f,i'插入col1

然后'e,f,i'通过将 的 binary_values 相加来计算 binary_value 'e''f'并且'i'对应的0001 0011 0000decimal_value304如下所示 -

+----+---------+----------------+---------------+
| id | element | binary_value   | decimal_value |
+----+---------+----------------+---------------+
|  5 | e       | 0000 0001 0000 |            16 |
|  6 | f       | 0000 0010 0000 |            32 |
|  9 | i       | 0001 0000 0000 |           256 |
+----+---------+----------------+---------------+
|    | e,f,i   | 0001 0011 0000 |           304 |
+----+---------+----------------+---------------+

因此要进入'e,f,i'我们col1使用以下查询 -

INSERT INTO table1  VALUES (1, 304);

然后我们检查存在于table1-

SELECT * FROM table1;
+----+-------+
| id | col1  |
+----+-------+
|  1 | e,f,i |
+----+-------+

我们看到在第一行我们的值为col1as'e,f,i'

同样,假设我们想将值 -'a,j'插入col1

然后binary_value'a,j'是通过将binary_values'a''j'is相加来计算的0010 0000 0001,对应的decimal_value513如下图所示——

+----+---------+----------------+---------------+
| id | element | binary_value   | decimal_value |
+----+---------+----------------+---------------+
|  1 | a       | 0000 0000 0001 |             1 |
| 10 | j       | 0010 0000 0000 |           512 |
+----+---------+----------------+---------------+
|    | a,j     | 0010 0000 0001 |           513 |
+----+---------+----------------+---------------+

因此要进入'a,j'我们col1使用以下查询 -

INSERT INTO table1  VALUES (2, 513);

然后我们检查存在于table1-

SELECT * FROM table1;
+----+-------+
| id | col1  |
+----+-------+
|  1 | e,f,i |
|  2 | a,j   |
+----+-------+

我们看到在第二行我们的值为col1as'a,j'

同样,假设我们想将值 -'b,d,h,i'插入col1

然后的 binary_value是通过将,的'b,d,h,i'binary_values 相加计算得到的,'b'对应的decimal_value如下所示'd''h''i'0001 1000 1010394

+----+---------+----------------+---------------+
| id | element | binary_value   | decimal_value |
+----+---------+----------------+---------------+
|  2 | b       | 0000 0000 0010 |             2 |
|  4 | d       | 0000 0000 1000 |             8 |
|  8 | h       | 0000 1000 0000 |           128 |
|  9 | i       | 0001 0000 0000 |           256 |
+----+---------+----------------+---------------+
|    | b,d,h,i | 0001 1000 1010 |           394 |
+----+---------+----------------+---------------+

因此要进入'b,d,h,i'我们col1使用以下查询 -

INSERT INTO table1  VALUES (3, 394);

然后我们检查存在于table1-

SELECT * FROM table1;
+----+---------+
| id | col1    |
+----+---------+
|  1 | e,f,i   |
|  2 | a,j     |
|  3 | b,d,h,i |
+----+---------+

我们看到在第三行我们的值为col1as'b,d,h,i'

于 2021-09-26T08:07:43.540 回答