ENUM
一种可自定义的数据类型,包含一组值
ENUM 是一种可自定义的数据类型,由一组静态、有序的值组成。
在PostgreSQL 8.3中添加了ENUM 数据类型。
创建ENUM类型
创建一个ENUM类型
使用CREATE TYPE 来创建ENUM 类型
CREATE TYPE enum_test AS ENUM ('foo', 'bar', 'baz');
请注意,ENUM 类型中的每个值最多可以包含 63 个字节(NAMEDATALEN - 1),包括空格和非 ASCII 字符。
在表定义中使用ENUM类型
像其他类型一样使用ENUM 类型名称
CREATE TABLE thing (
thing_id INT NOT NULL,
thing_type enum_test
);
修改ENUM类型
添加值
从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 类型中值的顺序。
删除ENUM类型
删除未使用的ENUM类型
DROP TYPE enum_other;
删除在表中使用的ENUM类型
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 文档: 枚举类型
有用链接
- Enums vs Check Constraints in Postgres - 2022 年 12 月 Craig Kerstiens / Crunchy Data 的博客文章
- Find all enum columns in PostgreSQL database - 2019 年 6 月 Bart Gawrych / Dataedo 的博客文章
- Looking up Enum types and values in Postgres - 2019 年 5 月 Sadique Ali Koothumadan 的博客文章
- Enumerated Data Types - Postgres Guide
