更新时间: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所示。
- NULL值的下标为NULL。
- 宽松模式下或者INSERT IGNORE语法插入非法值时,会插入0值,即空串。当有枚举成员为空串时,空串为合法值,且整型值为空串的位置下标,非法值的字符串值也为空串,但整型值为0。
M-Compatibility支持的ENUM类型请如表2所示。
|
名称 |
描述 |
存储空间 |
|---|---|---|
|
ENUM |
枚举类型,用于存储和操作可选的枚举值。
|
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) |
父主题: 数据类型