A Comprehensive Guide to Using MySQL ENUM

摘要:在本教程中,您将学习如何使用 MySQL ENUM数据类型来定义存储枚举值的列。

MySQL ENUM数据类型简介

在 MySQL 中, ENUM是一个字符串对象,其值是从创建列时定义的允许值列表中选择的。

ENUM数据类型具有以下优点:

  • 紧凑的数据存储。 MySQL ENUM使用数字索引(1、2、3、...)来表示字符串值。
  • 可读的查询和输出。

要定义ENUM列,请使用以下语法:

CREATE TABLE table_name (
    ...
    col ENUM ('value1','value2','value3'),
    ...
);
Code language: SQL (Structured Query Language) (sql)

在此语法中,可以有三个以上的枚举值。但是,最好将枚举值的数量保持在 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
);
Code language: SQL (Structured Query Language) (sql)

priority列仅接受三个值LowMediumHigh 。在幕后,MySQL 将每个枚举成员映射到一个数字索引。在本例中, LowMediumHigh分别映射到 1、2 和 3。

插入 MySQL ENUM

要将数据插入ENUM列,请使用预定义列表中的枚举值。例如,以下语句将新行插入到tickets表中。

INSERT INTO tickets(title, priority)
VALUES('Scan virus for computer A', 'High');
Code language: SQL (Structured Query Language) (sql)

除了枚举值之外,您还可以使用枚举成员的数字索引将数据插入到ENUM列中。例如,以下语句插入一个具有Low优先级的新票证:

INSERT INTO tickets(title, priority)
VALUES('Upgrade Windows OS for all computers', 1);
Code language: SQL (Structured Query Language) (sql)

在此示例中,我们没有使用Low枚举值,而是使用值 1。由于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');       
Code language: SQL (Structured Query Language) (sql)

因为我们将priority定义为NOT NULL列,所以当您插入新行而不指定priority级列的值时,MySQL 将使用第一个枚举成员作为默认值。

请参阅以下声明:

INSERT INTO tickets(title)
VALUES('Refresh the computer of Ms. Lily');
Code language: SQL (Structured Query Language) (sql)

在非严格SQL模式下,如果向ENUM列插入无效值,MySQL将使用数字索引为0空字符串''进行插入。如果启用了严格 SQL 模式,尝试插入无效的ENUM值将导致错误。

请注意,如果ENUM列被定义为可为空列,则它可以接受NULL值。

过滤 MySQL ENUM

以下语句获取所有高优先级票证:

SELECT 
    *
FROM
    tickets
WHERE
    priority = 'High';
Code language: SQL (Structured Query Language) (sql)
MySQL ENUM - filtering example

由于枚举成员 'High' 映射到 3,因此以下查询返回相同的结果集:

SELECT 
    *
FROM
    tickets
WHERE
    priority = 3;
Code language: SQL (Structured Query Language) (sql)

对 MySQL ENUM值进行排序

MySQL 根据索引号对ENUM进行排序。因此,成员的顺序取决于它们在枚举列表中的定义方式。

以下查询Low票证并按优先级High对它们进行排序:

SELECT 
    title, priority
FROM
    tickets
ORDER BY priority DESC;
Code language: SQL (Structured Query Language) (sql)
MySQL ENUM sorting

在创建列时按照您想要的排序顺序定义枚举值始终是一个好习惯。

MySQL ENUM 缺点

MySQL ENUM有以下缺点:

  1. 更改枚举成员需要使用ALTER TABLE语句重建整个表,这在资源和时间方面都是昂贵的。
  2. 获取完整的枚举列表很复杂,因为您需要访问information_schema数据库:
    选择 
        列类型
    从
        information_schema.COLUMNS
    在哪里
        TABLE_NAME = '门票'
            AND COLUMN_NAME = '优先级';
    
  3. 移植到其他 RDBMS 可能是一个问题,因为ENUM不是 SQL 标准,并且没有多少数据库系统支持它。
  4. 向枚举列表添加更多属性是不可能的。假设您想为每个优先级添加服务协议,例如,高(24 小时)、中(1-2 天)、低(1 周),则ENUM是不可能的。在这种情况下,您需要有一个单独的表来存储优先级列表,例如,priority(id, name, sort_order, description),并将tickets表中的priority字段替换为引用priorities表的id字段的priority_id
  5. 与查找表( priorities )相比,枚举列表是不可重用的。例如,如果您想创建一个名为tasks的新表并想重用优先级列表,这是不可能的。

在本教程中,我们向您介绍了 MySQL ENUM数据类型以及如何使用它来定义存储枚举值的列。

本教程有帮助吗?