根据https://www.postgresql.org/docs/current/datatype-enum.html
枚举值在磁盘上占用四个字节。
这似乎是一个奇怪的选择。当然,为了速度,枚举标签被映射到固定大小的整数,但为什么是 4 个字节呢?
大多数时候,枚举仅用于少数选项;1 个字节就足够了。
可以理解的是,设计者可能想要满足偶尔较大的枚举的需求。在野外见过的最大的枚举是什么?我可以想象一个用于例如国家代码。这是最后一次计数的 249;再多几个国家就会溢出 1 字节。我可以明白将其设置为 2 个字节的理由。
但为什么是4?有没有人使用过超过 65536 个案例的数据库枚举?Postgres 真的可以与那么多人一起工作吗?
在底层,枚举值是 a
real
,而不是 aninteger
,这就是它占用四个字节的原因。查看系统目录:enumtypid
是数据类型的 OID(来自pg_type
),enumsortorder
是存储在表中的实际值,enumlabel
是标签。要了解为什么
real
使用,请查看该示例:到目前为止,这并不奇怪。
这也很清楚。
啊! 因为
'millionaire' < 'billionaire'
,它的排序顺序必须在'rich'
和 之间'billionaire'
。对于integer
,我们必须将 的排序顺序更改'billionaire'
为 4 以便为新标签腾出空间。但这是不可能的,因为 3 的内部值可能已经存储在某个表中,并且我们当然不能重写所有这些表。显而易见的答案是使用浮点值,以便我们可以在现有值之间插入新值。
我们必须“浪费”四个字节,因为没有更短的浮点数据类型。如果您考虑到每个表行都有 23 个字节的开销,并且您想要保存的三个字节中的大部分很可能会因对齐要求而导致填充丢失,那么您会发现浪费并没有那么严重。