枚举
一个包含一组值的自定义数据类型
ENUM
是一种自定义数据类型,包含一组静态的有序值。
ENUM
数据类型在 PostgreSQL 8.3 中添加。
创建枚举类型
创建枚举类型
使用 CREATE TYPE
创建 ENUM
类型
CREATE TYPE enum_test AS ENUM ('foo', 'bar', 'baz');
请注意,ENUM
类型中的每个值最多可以包含 63 个字节(NAMEDATALEN
- 1),包括空格和非 ASCII 字符。
在表定义中使用枚举类型
像使用任何其他类型一样使用 ENUM
类型的名称
CREATE TABLE thing ( thing_id INT NOT NULL, thing_type enum_test );
修改枚举类型
添加值
从 PostgreSQL 9.1 开始,可以使用 ALTER TYPE
将值添加到现有的 ENUM
类型中,例如:
ALTER TYPE enum_test ADD VALUE 'boo'; ALTER TYPE enum_test ADD VALUE 'bee' BEFORE 'boo';
从 PostgreSQL 9.3 开始,可以使用 IF NOT EXISTS
子句以幂等的方式将值添加到现有的 ENUM
类型中,例如:
ALTER TYPE enum_test ADD VALUE IF NOT EXISTS 'boo';
重命名值
从 PostgreSQL 10 开始,可以使用 ALTER TYPE
重命名现有 ENUM
类型中的值,例如:
ALTER TYPE enum_test RENAME VALUE 'boo' TO 'baa';
删除值
无法从 ENUM
类型中删除值。有关为何未实现此功能的技术概述,请参阅提交 af3ee8a0。
更改值的顺序
无法更改 ENUM
类型中值的顺序。
删除枚举类型
删除未使用的枚举类型
使用 DROP TYPE
DROP TYPE enum_other;
删除表中使用的枚举类型
DROP TYPE enum_test CASCADE;
但请注意,这将删除使用此 ENUM
的所有列。
psql 命令
\dT+ typename
将显示 ENUM
类型的详细信息,包括它包含的所有值。请参见下面的示例。
更改历史记录
- PostgreSQL 10
- 可以重命名现有
ENUM
类型中的值(提交 0ab9c56d)
- 可以重命名现有
- PostgreSQL 9.3
- 可以使用
IF NOT EXISTS
子句以幂等的方式将值添加到现有的ENUM
类型中(提交 6d12b68c)
- 可以使用
- PostgreSQL 9.1
- 可以将新值添加到现有的
ENUM
类型中(提交 84c123be)
- 可以将新值添加到现有的
- PostgreSQL 8.3
- 添加(提交 57690c68)
示例
创建 ENUM
类型
postgres=# CREATE TYPE enum_test AS ENUM ('foo', 'bar', 'baz'); CREATE TYPE postgres=# \dT List of data types Schema | Name | Description --------+-----------+------------- public | enum_test | (1 row) postgres=# \dT+ List of data types Schema | Name | Internal name | Size | Elements | Owner | Access privileges | Description --------+-----------+---------------+------+----------+----------+-------------------+------------- public | enum_test | enum_test | 4 | foo +| postgres | | | | | | bar +| | | | | | | baz | | | (1 row)
使用 ENUM
类型创建表
postgres=# CREATE TABLE thing (thing_id INT NOT NULL, thing_type enum_test); CREATE TABLE postgres=# \d thing Table "public.thing" Column | Type | Collation | Nullable | Default ------------+-----------+-----------+----------+--------- thing_id | integer | | not null | thing_type | enum_test | | |
将数据插入 ENUM
类型
postgres=# INSERT INTO thing values(1,'foo'); INSERT 0 1 postgres=# INSERT INTO thing values(2,'bar'); INSERT 0 1 postgres=# INSERT INTO thing values(1,'baa'); ERROR: invalid input value for enum enum_test: "baa" LINE 1: INSERT INTO thing values(1,'baa');
选择 ENUM
类型
postgres=# SELECT * FROM thing; thing_id | thing_type ----------+------------ 1 | foo 2 | bar (2 rows) postgres=# SELECT * FROM thing WHERE thing_type='bar'; thing_id | thing_type ----------+------------ 1 | bar (1 row) postgres=# SELECT * FROM thing WHERE thing_type='baa'; ERROR: invalid input value for enum enum_test: "baa" LINE 1: SELECT * FROM thing WHERE thing_type='baa'; ^
删除 ENUM
类型
postgres=# DROP TYPE enum_other; DROP TYPE postgres=# DROP TYPE enum_test; ERROR: cannot drop type enum_test because other objects depend on it DETAIL: column thing_type of table thing depends on type enum_test postgres=# DROP TYPE enum_test CASCADE; NOTICE: drop cascades to column thing_type of table thing DROP TYPE postgres=# \d thing Table "public.thing" Column | Type | Collation | Nullable | Default ----------+---------+-----------+----------+--------- thing_id | integer | | not null |
参考
- PostgreSQL 文档: 枚举类型
有用链接
- Postgres 中的枚举与检查约束 - Craig Kerstiens / Crunchy Data 于 2022 年 12 月发表的博文
- 在 PostgreSQL 数据库中查找所有枚举列 - Bart Gawrych / Dataedo 于 2019 年 6 月发表的博文
- 在 Postgres 中查找枚举类型和值 - Sadique Ali Koothumadan 于 2019 年 5 月发表的博文
- 枚举数据类型 - Postgres 指南