更新时间:2025-10-23 GMT+08:00

枚举类型

ENUM是一个字符串类型,该类型只在建表时可以创建,创建的ENUM类型会提供一个列表包含所有可选的枚举值。ENUM的合法值为列表中的一个值,该值可以由枚举值的字符串形式或者枚举的下标表示。

ENUM创建语法如下:

ENUM('val1','val2',...) [CHARACTER SET charset_name] [COLLATE collation_name]

ENUM类型的枚举值的字符串值和整型值一一对应,在操作时含义相同。以 ENUM('beijing', 'shanghai', 'nanjing', 'wuhan') 为例,枚举值的字符串和整型值对应关系如表1所示。

表1 枚举类型成员字符串值和整型值(下标)对应关系

字符串值

整型下标

NULL

NULL

''

0

'beijing'

1

'shanghai'

2

'nanjing'

3

'wuhan'

4

  1. NULL值的下标为NULL。
  2. 宽松模式下或者INSERT IGNORE语法插入非法值时,会插入0值,即空串。当有枚举成员为空串时,空串为合法值,且整型值为空串的位置下标,非法值的字符串值也为空串,但整型值为0。

M-Compatibility支持的ENUM类型请如表2所示。

表2 枚举类型

名称

描述

存储空间

ENUM

枚举类型,用于存储和操作可选的枚举值。

  • 输入格式:
    • 字符串,可选的枚举成员之一。
    • 整型,枚举成员对应的位置下标之一。
  • 输出格式:
    • 枚举创建时的枚举成员字符串值。
  • 取值范围:
    • 最多支持创建65535个枚举成员。
    • 枚举成员所代表的字符串值或整型值之一。

6字节

  • ENUM数据类型的输入合法校验受sql_mode影响。宽松模式下,ENUM类型列输入不合法的值,会插入0值,即空串,严格模式下,插入不合法的值,会报错。
  • ENUM数据类型创建时的每个成员值需要唯一。出现重复成员值,严格模式下报错,宽松模式下支持创建,但默认使用重复值中第一个出现的。
  • ENUM数据类型支持字符集与字符序特性,且校验成员值是否重复与ENUM列上的字符序特性有关。
  • ENUM数据类型不支持作为分区键。
  • ENUM数据类型上的索引仅支持通过整型查找,使用字符串值无法走索引。
  • 不建议ENUM成员值为数值,容易与下标值出现混淆。
  • 当前ENUM类型与其它类型比较不支持走索引扫描,需要在ENUM类型的列上,根据需要查询的数据类型,创建函数表达式索引来支持走索引扫描。

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
--创建表和ENUM数据类型
m_db=# CREATE TABLE test_enum(c1 ENUM('abc','efg','中文','汉字'));
CREATE TABLE

-- 查看表结构
m_db=# select pg_get_tabledef('test_enum');
                                      pg_get_tabledef                                      
-------------------------------------------------------------------------------------------
 SET search_path = public;                                                                +
 CREATE TABLE test_enum (                                                                 +
     c1 ENUM('abc', 'efg', '中文', '汉字') CHARACTER SET `UTF8` COLLATE utf8mb4_general_ci+
 )                                                                                        +
 CHARACTER SET = "UTF8" COLLATE = "utf8mb4_general_ci"                                    +
 WITH (orientation=row, compression=no, storage_type=USTORE, segment=off);
(1 row)

-- 插入字符串数据
m_db=# insert into test_enum values('abc');
INSERT 0 1
m_db=# insert into test_enum values('中文');
INSERT 0 1

-- 插入整型数据
m_db=# insert into test_enum values(2),(4);
INSERT 0 2

-- 字符串形式查询数据
m_db=# select * from test_enum where c1 = 'efg' or c1 = '中文';
  c1  
------
 中文
 efg
(2 rows)

-- 整型值形式查询数据
m_db=# select * from test_enum where c1 = 1 or c1 = 4;
  c1  
------
 abc
 汉字
(2 rows)

--删除表
m_db=# drop table test_enum;
DROP TABLE

--创建表和ENUM数据类型
m_db=# create table t1(id int, c1 enum('a','bb','ccc'));
CREATE TABLE

-- 直接创建ENUM类型的索引无法支持走索引扫描
m_db=# create index idx_1 on t1(c1);
CREATE INDEX

m_db=# explain select c1 from t1 where c1 = 'a';
                     QUERY PLAN                      
-----------------------------------------------------
 Seq Scan on t1  (cost=0.00..59.00 rows=15 width=32)
   Filter: (cast_to_cstring(c1) = 'a'::text)
(2 rows)

-- 字符串查询,创建cast_to_cstring 函数索引,支持索引扫描
m_db=# create index id_t1 on t1((cast_to_cstring(c1)));
CREATE INDEX

m_db=# explain select c1 from t1 where c1 = 'a';
                             QUERY PLAN                             
--------------------------------------------------------------------
 Bitmap Heap Scan on t1  (cost=4.30..13.78 rows=6 width=32)
   Recheck Cond: (cast_to_cstring(c1) = 'a'::text)
   ->  Bitmap Index Scan on id_t1  (cost=0.00..4.30 rows=6 width=0)
         Index Cond: (cast_to_cstring(c1) = 'a'::text)
(4 rows)

-- 整型查询,创建cast_to_int8 函数索引,支持索引扫描
m_db=# create index id_t2 on t1((cast_to_int8(c1)));
CREATE INDEX

m_db=# explain select c1 from t1 where c1 = 5;
                             QUERY PLAN                             
--------------------------------------------------------------------
 Bitmap Heap Scan on t1  (cost=4.30..13.78 rows=6 width=32)
   Recheck Cond: (cast_to_int8(c1) = 5)
   ->  Bitmap Index Scan on id_t2  (cost=0.00..4.30 rows=6 width=0)
         Index Cond: (cast_to_int8(c1) = 5)
(4 rows)