mysql 中的enum枚举类型

本文探讨了在MySQL中使用ENUM类型的潜在问题,特别是在将其值定义为数字时。ENUM实际上是一种字符串对象,其值是从预定义列表中选取。文章还讨论了ENUM值的索引、排序规则以及如何正确处理无效值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感觉最近被enum坑惨了,原以为绝对没有问题的sql神奇的错了,数据离谱到我都不信,php开发使用enum类型绝对不是一个省事的选择,把enum的value定义为数字(0,1,2)之类的更是坑爹。

以下内容转载于:http://www.cnblogs.com/skillCoding/archive/2012/03/14/2395404.html,感谢原作者。

ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举。

在下列某些情况下,值也可以是空串("") 或 NULL

  • 如果将一个无效值插入一个 ENUM (即,一个不在允许值列表中的字符串),空字符串将作为一个特殊的错误值被插入。事实上,这个字符串有别于一个"普通的"空字符串,因为这个字符串有个数字索引值为 0。稍后有更详细描述。
  • 如果一个 ENUM 被声明为 NULLNULL 也是该列的一个合法值,并且该列的缺省值也将为 NULL 。如果一个 ENUM 被声明为 NOT NULL,该列的缺省值将是该列表所允许值的第一个成员。

每个枚举值均有一个索引值:

  • 在列说明中列表值所允许的成员值被从 1 开始编号。
  • 空字符串错误值的索引值为 0。这就意味着,你可以使用下面所示的 SELECT 语句找出被赋于无效 ENUM值的记录行。
    mysql> SELECT * FROM tbl_name WHERE enum_col=0;
  • NULL 值的索引值为 NULL

例如,指定为 ENUM("one", "two", "three") 的一个列,可以有下面所显示的任一值。每个值的索引值也如下所示:

索引值
NULL NULL
"" 0
"one" 1
"two" 2
"three" 3

换个枚举最大可以有 65535 个成员值。

从 MySQL 3.23.51 开始,当表被创建时,ENUM 值尾部的空格将会自动删除。

当为一个 ENUM 列赋值时,字母的大小写是无关紧要的。然而,以后从列中检索出来的值的大小写却是匹配于创建表时所指定的允许值。

如果在一个数字语境中检索一个ENUM,列值的索引值将被返回。例如,你可以像这样使用数字值检索一个 ENUM 列:

mysql> SELECT enum_col+0 FROM tbl_name;

如果将一个数字存储到一个 ENUM 中,数字被当作为一个索引值,并且存储的值是该索引值所对应的枚举成员。(但是,这在 LOAD DATA 将不能工作,因为它视所有的输入均为字符串。) 在一个 ENUM 字符串中存储数字是不明智的,因为它可能会打乱思维。

ENUM 值依照列规格说明中的列表顺序进行排序。(换句话说,ENUM 值依照它们的索引号排序。)举例来说,对于 ENUM("a", "b") "a" 排在 "b" 后,但是对于 ENUM("b", "a") "b" 却排在 "a" 之前。空字符串排在非空字符串前,NULL 值排在其它所有的枚举值前。为了防止意想不到的结果,建议依照字母的顺序定义 ENUM 列表。也可以通过使用GROUP BY CONCAT(col) 来确定该以字母顺序排序而不是以索引值。

如果希望得到一个 ENUM 列的所有可能值,可以使用 SHOW COLUMNS FROM table_name LIKE enum_colum


### MySQLENUM 数据类型的定义、用法和特性 #### 1. 定义 ENUM 是一种特殊的字符串对象,其必须是预定义集合中的一个。它在创建表时通过指定可能的来定义,字段的只能是枚举列表中的一个[^4]。这种数据类型非常适合存储有限选项的场景,例如星期('Monday', 'Tuesday', 'Wednesday' 等)或状态('Open', 'Closed', 'Pending' 等)。 #### 2. 使用场景 ENUM 类型适用于以下场景: - 存储具有固定选项的数据,例如性别('Male', 'Female')、状态('Active', 'Inactive')等。 - 需要确保字段的完整性和一致性,避免输入无效。 - 在存储空间和查询效率方面具有一定优势的场景[^2]。 #### 3. 特性 - **存储效率**:MySQL 内部将 ENUM 存储为整数索引,从而节省存储空间。如果枚举列表包含少于或等于 255 个元素,则使用 1 字节存储;否则使用 2 字节存储[^5]。 - **排序与比较**:ENUM 按照定义时的顺序进行排序和比较,而不是基于字符串的字典顺序[^4]。 - **默认处理**:如果插入的不在枚举列表中,MySQL 将其视为错误,并根据 SQL 模式决定是否插入空字符串或生成警告信息[^5]。 - **索引支持**:ENUM 字段可以被索引,以加速查询操作[^4]。 #### 4. 示例代码 以下是一个使用 ENUM 数据类型的示例: ```sql CREATE TABLE employees ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), status ENUM('Active', 'Inactive', 'Terminated') NOT NULL ); ``` 在上述代码中,`status` 字段使用了 ENUM 类型,允许的为 'Active', 'Inactive' 和 'Terminated'。 插入数据时,只能使用预定义的枚举之一: ```sql INSERT INTO employees (name, status) VALUES ('John Doe', 'Active'); INSERT INTO employees (name, status) VALUES ('Jane Smith', 'Inactive'); ``` 尝试插入无效会导致错误: ```sql INSERT INTO employees (name, status) VALUES ('Alice Johnson', 'Unknown'); -- 错误 ``` #### 5. 注意事项 - 如果需要更改 ENUM 列的列表,必须使用 `ALTER TABLE` 语句,这可能会导致表锁定和性能问题。 - ENUM是区分大小写的,因此在定义和插入时需注意大小写的一致性[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值