MySQL enum vs. set

For MySQL Data type of "enum" and "set" what are the differences and advantages and disadvantages of using one versus the other?

Example data type:

  • enum('A', 'B', 'C')
  • set('A', 'B', 'C')

The only difference that I am aware of is that ENUM only allows one value to be selected versus SET allows multiple values to be selected.

75158 次浏览

正如 MySQL 文档指出的:

ENUM 或 SET 列的定义确实充当值的约束 输入到列中。如果值没有输入到列中,则会发生错误 满足以下条件:

ENUM 值必须是列定义中列出的值之一,或者 它的内部数值等价物。该值不能是错误 值(即0或空字符串) ENUM (‘ a’、‘ b’、‘ c’) ,诸如“、‘ d’或‘ ax’之类的值是非法的,并且是 被拒绝了。

SET 值必须是空字符串或仅由 列定义中以逗号分隔的值 column defined as SET('a','b','c'), values such as 'd' or 'a,b,c,d' 是非法的,并被拒绝。

Enum 和 Set 完全取决于需求,比如如果您有一个单选按钮列表,一次只能选择一个,那么使用 Enum。如果您有一个复选框列表,其中可以同时选择多个项目,请使用 set。

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 中,您会发现 预备实际上是一个集合。可以存储声明的每个属性组合。

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实际上每次只能存储一次。你会发现最后两行的结果都是空的。

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

其实很简单:

当您定义一个 ENUM (‘ Yes’,‘ No’,‘ Maybe’),然后您 必须的INSERT 只有其中一个值(或其位置索引号)

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

希望这样能解释清楚。

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

ENUM —— > 只选择要插入的可用值之一。

(no _ null,no _ any _ copy)


选择任意组合或单个值(如 SET)并将它们插入。

(空值,个人值,全部可用值)

I addition to the points already mentioned in the answers so far given I am adding an additional point on the difference -

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

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

这一点如下所示-

ENUM 示例-

我创建了 table1表,其中列 col1的数据类型为 ENUM('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

因此,为了在 col1中输入 'e',我们使用以下查询-

INSERT INTO table1  VALUES (1, 5);

然后我们检查 table1-中的值

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

and we see that in first row we have the value of col1 as 'e'

Again, suppose we want to insert the value - 'i' into col1

'i'的索引是 9

因此,为了在 col1中输入 'i',我们使用以下查询-

INSERT INTO table1  VALUES (2, 9);

然后我们检查 table1-中的值

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

我们看到在第二行,我们有 col1作为 'i'的值

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

'a'的索引是 1

因此,为了在 col1中输入 'a',我们使用以下查询-

INSERT INTO table1  VALUES (3, 1);

然后我们检查 table1-中的值

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

我们看到在第三行我们有 col1作为 'a'的值


SET 例子-

I create table table1 with column col1 having data type of SET('a','b','c','d','e','f','g','h','i','j') with the following table structure -

| 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'的二进制值相加,得到 'e,f,i'的二进制值 0001 0011 0000,相应的十进制值 304,如下所示

+----+---------+----------------+---------------+
| 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 |
+----+---------+----------------+---------------+

因此,为了在 col1中输入 'e,f,i',我们使用以下查询-

INSERT INTO table1  VALUES (1, 304);

然后我们检查 table1-中的值

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

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

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

然后将 'a''j'的二进制值相加,得到 'a,j'的二进制值 0010 0000 0001,相应的十进制值 513,如下所示

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

Thus to enter 'a,j' into col1 we use the following query -

INSERT INTO table1  VALUES (2, 513);

然后我们检查 table1-中的值

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

我们看到在第二行,我们有 col1作为 'a,j'的值

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

然后将 'b''d''h''i'的二进制值相加,得到 'b,d,h,i'的二进制值 0001 1000 1010,相应的十进制值 394,如下所示

+----+---------+----------------+---------------+
| 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 |
+----+---------+----------------+---------------+

因此,为了在 col1中输入 'b,d,h,i',我们使用以下查询-

INSERT INTO table1  VALUES (3, 394);

然后我们检查 table1-中的值

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

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