TL;DR 版本:担心这个可能不值得你花时间。
长版:
Postgres 中有枚举类型:
create type myenum as enum('foo', 'bar');
与使用 varchar 或整数字段相比,使用它有利有弊。主要是专业人士恕我直言。
就大小而言,它存储为oid,所以int32 类型。这使它比填充了典型值的 varchar 更小(例如,'draft'、'published'、'pending'、'completed',无论您的枚举是什么),并且与 int 类型的大小相同。如果您的值很少,smallint / int16 无疑会更小。您的一些性能变化将来自那里(较小与较大的字段,即几乎可以忽略不计)。
在每种情况下都可以进行验证,无论是通过enum 的内置目录查找,还是varchar 或int 的检查约束或外键。您的一些性能变化将来自那里,而且可能也不值得您花时间。
枚举类型的另一个好处是它是有序的。在上面的示例中,'foo'::myenum < 'bar'::myenum',使得order by enumcol 成为可能。要使用varchar 或int 实现相同的目的,您需要一个带有sortidx 列或其他内容的单独表......在这种情况下,如果您想订购,枚举可以产生巨大的好处通过您的枚举值。这给我们带来了(恕我直言)唯一的问题,这与枚举类型在目录中的存储方式有关......
在内部,每个枚举的值都带有一个oid,后者按原样存储在表中。所以它在技术上是一个int32。创建枚举类型时,其值以正确的顺序存储在目录中。在上面的示例中,'foo' 的oid 将低于'bar'。这使得 Postgres 按枚举值排序非常有效,因为它相当于对 int32 值进行排序。
但是,当您 ALTER 您的枚举时,您最终可能会更改该顺序。例如,假设您将上述枚举更改为 myenum 现在是 ('foo', 'baz', 'bar')。出于与效率相关的原因,Postgres 不会为现有值分配新的oid 并重写使用它们的表,更不用说使使用它们的缓存查询计划无效了。相反,它的作用是在pg_catalog 中填充一个单独的字段,以使其产生正确的排序顺序。从那时起,按枚举字段排序需要额外的查找,这实际上相当于将表与带有sortidx 字段的单独值表连接起来——就像你对varchar 或@ 所做的那样987654351@ 如果您想对它们进行排序。
这通常很好并且完全可以接受。有时,它不是。如果没有,则有解决方案:更改具有枚举类型的表,并将它们的值更改为 varchar。还可以像您一样定位和调整使用它的功能和触发器。然后完全删除该类型,然后重新创建它以获取新的 oid 值。最后将表格改回原来的位置,并重新调整函数和触发器。不是微不足道的,但肯定是可行的。