likes
comments
collection
share

PostgerSQL技术问答08 - ENUM

作者站长头像
站长
· 阅读数 65

本文是《PostgreSQL技术问答》系列文章中的一篇。关于这个系列的由来,可以参阅开篇文章:

文章的编号只是一个标识,在系列中没有明确的逻辑顺序和意义。读者进行阅读时,不用太关注这个方面。

本文笔者想要来讨论一下在PostgreSQL中的ENUM,即枚举这一功能和特性。

什么是ENUM枚举

ENUM在编程语言中,是一个非常常见的概念。通常而言,ENUM即枚举,它是一个数据集合,这个集合中的元素是有限,有序、并且相对固定的,并作为一种特殊的数据类型。要使用这个数据类型,就只能使用这个集合中的某个元素。

ENUM的作用和好处在于:

  • 数据完整性: 使用ENUM可以确保数据只能是预定义的值,减少创建和使用无效数据的风险
  • 可读性: 枚举可以使数据更加可读,因为它通常使用一个字符串标签来描述数据的值,具有自解释性
  • 性能: 通常情况下,系统实际使用更简单的数据类型(如整数)来映射和实现枚举,相关处理更加高效
  • 有序:定义枚举值时,需要指定顺序,可以天然的作为排序的依据

一个常见的应用场景就是用户的性别,可以定义一个性别的枚举类型,只有“男”和“女”两种,使用时只能在两种中选择其一,保证了不会用到无效或者错误的数据,同时也保证了程序的可读性和容易理解。

笔者认为,在Postgres中,这个概念和实现,包括其设计的目的,其实也是类似的。笔者甚至觉得,在PG中,ENUM就是一个整数,但使用一个字符串标签,方便人类理解和使用。

这里顺便提一下,在JS中,其实是没有原生的枚举数据类型的,通常只能通过对象常量、符号等技术手段来实现和模拟。

PG中如何创建和使用枚举

下面的代码,展示了PG定义和使用ENUM的一般流程:


CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TABLE person (
    name text,
    current_mood mood
);

INSERT INTO person VALUES ('Moe', 'happy');
SELECT * FROM person WHERE current_mood = 'happy';
 name | current_mood
------+--------------
 Moe  | happy
(1 row)

这段示例代码我们可以看到:

  • ENUM是一种特殊的数据类型,可以使用数据类型定义的方式创建
  • ENUM的定义内容是一个字符串序列
  • 使用时,需要声明表字段类型为定义好的ENUM类型
  • 使用ENUM的方式,基本上和字符串是相同的,但这个字符串,被限制在ENUM定义的内容当中

如何修改ENUM

虽然这个操作是不建议的,因为枚举类型是相对固定的内容,最好在应用开发时进行很好的规划和设置。但Postgres支持对ENUM的定义和内容进行一定程度的修改。相关的操作通常使用Alter Type语句完成,下面是一些示例:


// 创建枚举
CREATE TYPE 角色 AS ENUM ('嘉宾', '主持人', '观众');

// 增加枚举值
ALTER TYPE 角色 ADD VALUE '志愿者';

// 修改枚举值
ALTER TYPE 角色 RENAME VALUE '主持人' TO '主持';

// 检查枚举
SELECT n.nspname AS schema, t.typname AS enum_type,  e.enumlabel AS
FROM pg_type t
    JOIN pg_enum e ON t.oid = e.enumtypid
    JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
ORDER BY
    n.nspname, t.typname, e.enumsortorder;

关于ENUM有什么需要注意的问题

关于在PG中使用ENUM需要注意的问题,这里简单总结一下:

  • ENUM本身是有序的,项目的排序,就是其在定义时的次序
  • ENUM标签是区分大小写的
  • 虽然看起来都是字符串,但不同的ENUM之间不能直接进行比较(用于关联或者排序),如果确实要这样做,可能需要先进行类型转换
  • 对ENUM修改需要注意对当前数据的影响
  • ENUM不支持直接的值的删除或者重新排序,如果确实要这么做,可以考虑使用临时数据表来进行操作
  • PG也没有提供非常简单的枚举定义查询的方式,现在一般通过查询系统表来实现

小结

本文讨论了Postgres中的一种特殊的数据类型:ENUM,即枚举型。包括了它的定义、使用场景,在Postgres中的一般的操作方式,和一些相关的限制,以及需要注意的问题。

转载自:https://juejin.cn/post/7375810931098894399
评论
请登录