MySQL ENUM 数据类型
简介:在本教程中,您将学习如何使用MySQL
ENUM数据类型来定义存储枚举值的列。
MySQL ENUM数据类型简介
MySQL中ENUM是一个字符串对象,其值是从列创建时定义的允许值列表中选择的。
ENUM数据类型提供了以下优点:
- 紧凑的数据存储。MySQL
ENUM使用数字索引(1,2,3,...)来表示字符串值。 - 可读的查询和输出。
ENUM列,请使用以下语法:
CREATE TABLE table_name (
...
col ENUM ('value1','value2','value3'),
...
);
在此语法中,您可以拥有三个以上的枚举值。但是,将枚举值的数量保持在20以内是一种很好的做法。
我们来看下面的例子。
假设,我们必须存储优先级为低,中,高的票证信息。要为priority列分配ENUM类型,请使用以下CREATE TABLE语句:
CREATE TABLE tickets (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
priority ENUM('Low', 'Medium', 'High') NOT NULL
);
priority列只接受三个值Low,Medium和High。在后台MySQL将每个枚举成员映射到数字索引。在这种情况下,Low,Medium,和High分别映射到1,2和3。
插入MySQL ENUM值
要将数据插入ENUM列,请使用预定义列表中的枚举值。例如,以下语句将新行插入tickets表中。
INSERT INTO tickets(title, priority)
VALUES('Scan virus for computer A', 'High');
除了枚举值之外,您还可以使用枚举成员的数字索引将数据插入到ENUM列中。例如,以下语句插入具有Low优先级的新票证:
INSERT INTO tickets(title, priority)
VALUES('Upgrade Windows OS for all computers', 1);
在此示例中,我们使用值1. 而不是使用枚举值Low。因为Low映射到1,所以它是可接受的。
让我们在tickets表中添加更多行:
INSERT INTO tickets(title, priority)
VALUES('Install Google Chrome for Mr. John', 'Medium'),
('Create a new user for the new employee David', 'High');
因为我们将列定义priority为NOT NULL列,所以当您插入新行而不指定priority列的值时,MySQL将使用第一个枚举成员作为默认值。
请参阅以下语法:
INSERT INTO tickets(title)
VALUES('Refresh the computer of Ms. Lily');
mysql> select * from tickets; +----+----------------------------------------------+----------+ | id | title | priority | +----+----------------------------------------------+----------+ | 1 | Scan virus for computer A | High | | 2 | Upgrade Windows OS for all computers | Low | | 3 | Install Google Chrome for Mr. John | Medium | | 4 | Create a new user for the new employee David | High | | 5 | Refresh the computer of Ms. Lily | Low | +----+----------------------------------------------+----------+ 5 rows in set (0.00 sec)在非严格SQL模式下,如果向
ENUM列中插入无效值,MySQL将使用''带有数字索引的空字符串0进行插入。如果启用了严格的SQL模式,尝试插入无效ENUM值将导致错误。
注意:如果
ENUM列定义为可以为空的列,则列可以接受NULL值。
过滤MySQL ENUM值
以下语句获取所有高优先级票证:SELECT
*
FROM
tickets
WHERE
priority = 'High';
+----+----------------------------------------------+----------+ | id | title | priority | +----+----------------------------------------------+----------+ | 1 | Scan virus for computer A | High | | 4 | Create a new user for the new employee David | High | +----+----------------------------------------------+----------+ 2 rows in set (0.00 sec)由于枚举成员“High”映射为3,因此以下查询返回相同的结果集:
SELECT
*
FROM
tickets
WHERE
priority = 3;
对MySQL ENUM值进行排序
MySQL 根据ENUM索引号对值进行排序。因此,成员的顺序取决于它们在枚举列表中的定义方式。
下面的查询选择的门票,并通过优先级排序,从他们High到Low:
SELECT
title, priority
FROM
tickets
ORDER BY priority DESC;
+----------------------------------------------+----------+ | title | priority | +----------------------------------------------+----------+ | Scan virus for computer A | High | | Create a new user for the new employee David | High | | Install Google Chrome for Mr. John | Medium | | Upgrade Windows OS for all computers | Low | | Refresh the computer of Ms. Lily | Low | +----------------------------------------------+----------+ 5 rows in set (0.00 sec)在创建列时始终按照要排序的顺序定义枚举值是一个好习惯。
MySQL ENUM的缺点
MySQLENUM有以下缺点:
- 更改枚举成员需要使用
ALTER TABLE语句重建整个表,这在资源和时间方面是有代价的。 - 获取完整的枚举列表很复杂,因为您需要访问
information_schema数据库:SELECT column_type FROM information_schema.COLUMNS WHERE TABLE_NAME = 'tickets' AND COLUMN_NAME = 'priority';+-----------------------------+ | column_type | +-----------------------------+ | enum('Low','Medium','High') | +-----------------------------+ 1 row in set (0.01 sec) - 移植到其他RDBMS可能是一个问题,因为
ENUM它不是SQL标准,并且没有多少数据库系统支持它。 - 在枚举列表中添加更多属性是不可能的。假设您要为每个优先级添加服务协议,例如,高(24h),中(1-2天),低(1周),
ENUM则不可能。在这种情况下,您需要有一个单独的表来存储优先级列表,例如,priority(id,name,sort_order,description),并通过priority表的priority_id对tickets表的id字段的引用替换表中的字段priorities。 - 与查找表(
priorities)相比,枚举列表不可重用。例如,如果要创建一个表tasks并希望重用优先级列表,则无法实现。
ENUM数据类型以及如何使用它来定义存储枚举值的列。 