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
数据类型以及如何使用它来定义存储枚举值的列。