跳到主要内容

枚举类型

PostgreSQL 枚举类型(Enum)是一种自定义数据类型,用来定义一组固定、有顺序的取值。它适合状态、阶段、类别等小而稳定的字段,例如订单状态、工单优先级、用户角色。

枚举值由数据库层校验。字段使用枚举类型后,只能写入该类型声明过的值,避免业务代码或多端写入时出现拼写不一致的问题。

适用场景

枚举类型适合:

  • 取值集合较小,且变化不频繁。
  • 取值本身不需要额外字段,例如名称、排序权重、是否启用、展示颜色。
  • 希望数据库直接限制字段取值,减少无效状态写入。

如果取值会频繁增删、需要展示名多语言、需要配置额外属性,或需要由运营人员在后台维护,建议使用字典表或关联表,而不是枚举类型。

建模方式适用场景
枚举类型小而稳定的固定取值,如 pendingpaidcancelled
check 约束简单字段限制,且不需要复用为多个表的类型
字典表 / 关联表取值需要额外属性、权限、排序、上下线或运营维护

创建枚举类型

可以通过控制台或 SQL 语句创建枚举类型。当前云开发控制台的 PostgreSQL 管理界面与 Supabase 控制台保持一致,适合直接管理枚举类型和枚举值。

  1. 进入 云开发平台/PostgreSQL 数据库 管理页面。
  2. 选择目标环境,进入数据库管理界面。
  3. 打开「枚举类型」管理页面。
  4. 点击「新建枚举类型」。
  5. 填写枚举类型名称,例如 order_status
  6. 依次填写枚举值,例如 pendingpaidshippedcancelled
  7. 确认后提交,等待枚举类型创建完成。

控制台会根据填写内容创建对应的 PostgreSQL 枚举类型,适合不熟悉 SQL 的成员进行结构配置。

枚举值区分大小写,建议统一使用小写英文标识,并在业务展示层转换为用户可见文案。

在表中使用枚举

创建表时,可以直接把字段类型声明为枚举类型。

create table public.orders (
id bigint generated by default as identity primary key,
user_id varchar(64) not null default auth.uid(),
status public.order_status not null default 'pending',
title text not null,
created_at timestamptz not null default now()
);

如果表已存在,可以通过 ALTER TABLE 新增枚举字段。

alter table public.orders
add column status public.order_status not null default 'pending';

写入和查询

插入或更新枚举字段时,写入枚举值对应的字符串即可。

insert into public.orders (title, status)
values ('示例订单', 'paid');

update public.orders
set status = 'shipped'
where id = 1;

查询时可以像普通字段一样过滤和排序。

select id, title, status, created_at
from public.orders
where status = 'paid'
order by created_at desc;

枚举值存在声明顺序,order by status 会按创建枚举时声明的顺序排序,而不是按字母顺序排序。需要按业务优先级排序时,可以把枚举声明顺序作为排序规则;如果排序规则经常变化,建议改用字典表保存排序权重。

通过 HTTP API 查询

通过 HTTP API 访问枚举字段时,可以使用普通字段过滤语法。

curl -X GET 'https://<envId>.api.tcloudbasegateway.com/v1/rdb/rest/orders?status=eq.paid' \
-H 'Authorization: Bearer <access_token>'

具体可用操作符以 查询数据 和 HTTP API 参考为准。

管理枚举值

可以通过 ALTER TYPE ... ADD VALUE 追加新的枚举值。

alter type public.order_status add value if not exists 'refunded';

也可以指定新值在枚举顺序中的位置。

alter type public.order_status add value if not exists 'processing' after 'paid';

重命名枚举值可以使用 ALTER TYPE ... RENAME VALUE

alter type public.order_status rename value 'shipped' to 'delivered';

注意事项:

  • 新增枚举值属于结构变更,建议纳入迁移脚本,并先在测试环境验证。
  • PostgreSQL 不支持直接删除枚举值;删除通常需要新建类型、迁移字段数据,再替换旧类型。
  • 如果 ALTER TYPE ... ADD VALUE 在事务中执行,新值通常需要等事务提交后才能被后续语句使用。
  • 已有枚举类型被表、函数、视图或策略引用时,重命名或替换前需要评估依赖影响。

查看枚举值

可以使用 enum_range 查看某个枚举类型的全部取值。

select enum_range(null::public.order_status);

也可以查询系统目录,便于同时查看多个枚举类型。

select
t.typname as enum_name,
e.enumlabel as enum_value,
e.enumsortorder as sort_order
from pg_type t
join pg_enum e on t.oid = e.enumtypid
join pg_namespace n on n.oid = t.typnamespace
where n.nspname = 'public'
order by t.typname, e.enumsortorder;

建模建议

  • 枚举适合表达稳定状态,不适合承载经常变化的业务配置。
  • 生产环境中追加枚举值比删除枚举值安全;设计时应预留状态演进路径。
  • 多端调用时,前端、服务端和数据库迁移脚本应复用同一套枚举值定义,避免出现未同步的状态。
  • 如果 RLS 策略依赖枚举字段,新增枚举值后需要同步检查相关策略,避免新状态下数据不可读或可被越权修改。