MySQL ENUM

时间:2019-11-20 08:52:11  来源:igfitidea点击:

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

MySQL ENUM数据类型简介

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

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

  • 紧凑的数据存储。
    MySQL ENUM使用数字索引(1、2、3,...)表示字符串值。

  • 可读的查询和输出。

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

CREATE TABLE table_name (
    ...
    col ENUM ('value1','value2','value3'),
    ...
);

使用此语法,您可以具有三个以上的枚举值。
但是,最好将枚举值的数量保持在20以下。

让我们看下面的例子。

假设我们必须存储优先级为:低,中和高的票证信息。
要为ENUM类型分配优先级列,请使用以下CREATE TABLE语句:

CREATE TABLE tickets (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(255) NOT NULL,
    priority ENUM('Low', 'Medium', 'High') NOT NULL
);

"优先级"列将仅接受"低","中"和"高"三个值。
在后台,MySQL将每个枚举成员映射到一个数字索引。
在这种情况下,低,中和高分别映射为1、2和3。

插入MySQL ENUM值

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

INSERT INTO tickets(title, priority)
VALUES('Scan virus for computer A', 'High');

除了枚举值,您还可以使用枚举成员的数字索引将数据插入到ENUM列中。
例如,以下语句插入一个低优先级的新故障单:

INSERT INTO tickets(title, priority)
VALUES('Upgrade Windows OS for all computers', 1);

在此示例中,我们使用值1代替了Low枚举值。
由于Low被映射为1,因此可以接受。

让我们在票证表中添加更多行:

INSERT INTO tickets(title, priority)
VALUES('Install Google Chrome for Mr. John', 'Medium'),
      ('Create a new user for the new employee David', 'High');

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

请参阅以下语句:

INSERT INTO tickets(title)
VALUES('Refresh the computer of Ms. Lily');

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

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

过滤MySQL ENUM值

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

SELECT 
    *
FROM
    tickets
WHERE
    priority = 'High';

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

SELECT 
    *
FROM
    tickets
WHERE
    priority = 3;

排序MySQL ENUM值

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

以下查询选择故障单,并按优先级从高到低对它们进行排序:

SELECT 
    title, priority
FROM
    tickets
ORDER BY priority DESC;

最好以创建列时要排序的顺序定义枚举值。

MySQL ENUM的缺点

MySQL ENUM具有以下缺点:

  • 更改枚举成员需要使用ALTER TABLE语句重建整个表,这在资源和时间上都很昂贵。

  • 获取完整的枚举列表很复杂,因为您需要访问information_schema数据库:

  • 移植到其他RDBMS可能是一个问题,因为ENUM不是SQL标准的,并且没有多少数据库系统支持它。

  • 将更多属性添加到枚举列表是不可能的。
    假设您想为每个优先级添加服务协议,例如,高(24h),中(1-2天),低(1周),则ENUM无法实现。
    在这种情况下,您需要一个单独的表来存储优先级列表,例如优先级(id,name,sort_order,description),并用引用优先级表的id字段的priority_id替换票证表中的优先级字段。

  • 与查找表(优先级)相比,枚举列表不可重用。
    例如,如果要创建一个名为task的新表并想重用优先级列表,则不可能。

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