AnENUM
是一个字符串对象,其值选自创建表时在列规范中显式枚举的允许值列表。
有关
类型语法和长度限制
,
请参阅第 11.3.1 节,“字符串数据类型语法” 。ENUM
该ENUM
类型具有以下优点:
在列具有一组有限的可能值的情况下紧凑的数据存储。您指定为输入值的字符串会自动编码为数字。有关该类型的存储要求,请参阅 第 11.7 节,“数据类型存储要求”
ENUM
。可读的查询和输出。这些数字被翻译回查询结果中的相应字符串。
以及这些需要考虑的潜在问题:
枚举值必须是带引号的字符串文字。例如,您可以创建一个包含
ENUM
如下列的表:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),
('polo shirt','small');
SELECT name, size FROM shirts WHERE size = 'medium';
+---------+--------+
| name | size |
+---------+--------+
| t-shirt | medium |
+---------+--------+
UPDATE shirts SET size = 'small' WHERE size = 'large';
COMMIT;
向此表中插入 100 万行值为 的
'medium'
行将需要 100 万字节的存储空间,而如果将实际字符串存储'medium'
在
VARCHAR
列中则需要 600 万字节。
每个枚举值都有一个索引:
列规范中列出的元素分配有索引号,从 1 开始。
空字符串错误值的索引值为 0。这意味着您可以使用以下
SELECT
语句查找ENUM
分配了无效值的行:mysql> SELECT * FROM tbl_name WHERE enum_col=0;
该
NULL
值的索引是NULL
。这里的术语“索引”是指枚举值列表中的位置。它与表索引无关。
例如,指定为的列ENUM('Mercury',
'Venus', 'Earth')
可以具有此处显示的任何值。还显示了每个值的索引。
价值 | 指数 |
---|---|
NULL |
NULL |
'' |
0 |
'Mercury' |
1个 |
'Venus' |
2个 |
'Earth' |
3个 |
一ENUM
列最多可以有 65,535 个不同的元素。
如果您ENUM
在数字上下文中检索值,则会返回列值的索引。ENUM
例如,您可以像这样从列
中检索数值
:
mysql> SELECT enum_col+0 FROM tbl_name;
ENUM
创建表时,
会自动从表定义中的成员值中删除尾随空格
。
检索时,存储在ENUM
列中的值使用列定义中使用的字母大小写显示。请注意,ENUM
可以为列分配字符集和排序规则。对于二进制或区分大小写的归类,在为列赋值时会考虑字母大小写。
如果将数字存储到ENUM
列中,则该数字被视为可能值的索引,存储的值是具有该索引的枚举成员。(但是,这不适用于,
LOAD DATA
它将所有输入都视为字符串。)如果数值被引用,并且在枚举值列表中没有匹配的字符串,它仍被解释为索引。由于这些原因,不建议ENUM
使用看起来像数字的枚举值来定义列,因为这很容易造成混淆。例如,以下列的枚举成员的字符串值为
'0'
、'1'
和
'2'
1
,但是、2
和
的数字索引值
3
:
numbers ENUM('0','1','2')
如果存储2
,它会被解释为索引值,并变为'1'
(索引为 2 的值)。如果你存储'2'
,它匹配一个枚举值,所以它被存储为
'2'
。如果存储'3'
,则它不匹配任何枚举值,因此将其视为索引并变为'2'
(索引为3的值)。
mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql> SELECT * FROM t;
+---------+
| numbers |
+---------+
| 1 |
| 2 |
| 2 |
+---------+
要确定列的所有可能值,请
ENUM
使用
并解析
输出列中的
定义
。SHOW COLUMNS
FROM
tbl_name
LIKE
'enum_col
'ENUM
Type
在 C API 中,ENUM
值以字符串形式返回。有关使用结果集元数据将它们与其他字符串区分开来的信息,请参阅
C API 基本数据结构。
枚举值也可以是空字符串 ( ''
) 或NULL
在某些情况下:
如果将无效值插入 an
ENUM
(即允许值列表中不存在的字符串),则会插入空字符串作为特殊错误值。该字符串的数值为 0,因此可以将该字符串与“普通”空字符串 区分开来。有关枚举值的数字索引的详细信息,请参阅枚举文字的索引值。如果启用了严格的 SQL 模式,则尝试插入无效
ENUM
值会导致错误。如果
ENUM
列声明为 permitNULL
,则该NULL
值为该列的有效值,默认值为NULL
。如果ENUM
声明了一个列NOT NULL
,则其默认值是允许值列表的第一个元素。
ENUM
值根据它们的索引号排序,这取决于枚举成员在列规范中列出的顺序。例如,
在for
'b'
之前排序。空字符串排在非空字符串之前,值排在所有其他枚举值之前。
'a'
ENUM('b', 'a')
NULL
为防止ORDER
BY
在列上使用子句时出现意外结果,请ENUM
使用以下技术之一:
按字母顺序指定
ENUM
列表。确保列按词法排序,而不是通过编码或 按索引号排序。
ORDER BY CAST(
col
AS CHAR)ORDER BY CONCAT(
col
)
枚举值不能是表达式,即使计算结果为字符串值也是如此。
例如,此CREATE TABLE
语句不起作用,因为该
CONCAT
函数不能用于构造枚举值:
CREATE TABLE sizes (
size ENUM('small', CONCAT('med','ium'), 'large')
);
您也不能将用户变量用作枚举值。这对语句不起作用 :
SET @mysize = 'medium';
CREATE TABLE sizes (
size ENUM('small', @mysize, 'large')
);
我们强烈建议您不要使用数字作为枚举值,因为它不会在适当
TINYINT
或
SMALLINT
类型上节省存储空间,并且如果您很容易混淆字符串和基础数字值(可能不相同)错误地引用
ENUM
值。如果确实使用数字作为枚举值,请始终将其括在引号中。如果省略引号,则该数字被视为索引。请参阅枚举文字的处理,了解如何将带引号的数字错误地用作数字索引值。
如果启用了严格的 SQL 模式,则定义中的重复值会导致警告或错误。