Postgresql枚举有哪些优缺点?

时间:2010-02-23 12:42:05

标签: database postgresql

在我工作的地方,我们使用postgres数据库(8.3很快就会迁移到8.4)。目前关于在数据库中使用枚举的争论很少。我个人不喜欢db enum类型。除此之外,它还将应用程序逻辑放在数据库中,并为代码和数据之间的不匹配创建了可能性。

我想知道postgres枚举的优点究竟是什么(除了可读性之外)还有什么不妥之处?

6 个答案:

答案 0 :(得分:33)

枚举的优点是:

  • 表现更好。您可以只显示从核心表中获取的内容,而不是使用单独的查找表将代码转换为值,或者具有将代码转换为值的应用程序逻辑。这在数据仓库应用程序中尤其有用。
  • Ad hoc SQL更容易编写

缺点是:

  • 将显示值编码到数据库中ddl是错误的形式。如果您将应用代码中的枚举值转换为不同的显示值,那么您将失去使用枚举的许多优势。
  • 添加值需要DDL更改
  • 使语言本地化变得困难
  • 数据库可移植性降低

答案 1 :(得分:3)

Enums结合了int的优点和字符串的优点:它们像int一样小而快,像字符串一样可读,还具有安全的附加优点(你不能错误地拼写枚举)。

但是,如果你不关心可读性,那么int就像枚举一样好。

答案 2 :(得分:0)

作为优势,您还有DB检查,没有其他枚举值无法记录在列中。对我来说最大的缺点是,枚举只能通过增加值来修改,但是自Postgres 9.1以来它已经过去了:https://stackoverflow.com/a/7834949/548473

答案 3 :(得分:0)

优势

  1. 减少存储:当定义了 255 个或更少的 ENUM 元素时,Postgres 每个元组仅使用 1 个字节,或者为 256~65535 个元素使用 2 个字节。这是因为 Postgres 不是存储值的常量文字,而是将索引存储在该值的有序集合中。对于非常大的表,这可能会显着节省存储空间。

  2. 任意排序

CREATE TABLE opening_hours(
    week_day ENUM ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
    opening_time TIME,
    closing_time TIME
);

如果您按week_day排序,它将按照您指定的顺序进行排序,这在上述情况下很方便。

  1. 廉价约束:枚举检查是否仅以廉价方式添加某些值,而不是检查应用程序代码或某些复杂的数据库约束。

缺点

  • 最终用户无法控制选项列表,因为 ENUM 是架构的一部分
  • 需要额外的查询才能查看选项列表
  • 字符串操作和函数不适用于 ENUM 这是因为 ENUM 是一种独立于内置数据类型(如 NUMERIC 或 TEXT)的数据类型。这可以通过在操作时将 ENUM 值转换为 TEXT 来克服。但是,使用 ORM 时可能会很痛苦。

答案 4 :(得分:0)

在 PostgreSQL 13 中,btree 索引现在支持重复数据删除。如果我们以以下实际示例为例,使用 ENUM 表示具有 1 亿行的日志表中的 HTTP 方法:

public | test_http_enum_idx | index | postgres | test | permanent   | 789 MB  | 
public | test_http_test_idx | index | postgres | test | permanent   | 789 MB  | 

我们可以看到两者的索引大小是相同的。对于非规范化表,每行节省几个字节并不能真正弥补缺点。

PG 13+ 的经验法则: 使用 ENUM 将列限制为一组固定/静态值;不要使用它们来节省磁盘空间。

可能的例外: 如果静态值的 ENUM 可以帮助您避免代价高昂的 JOIN 或 FK --- 那就去做吧;只需确保避免过早优化并在生产中衡量您的结果。

在做出决定时,请考虑像 Metabase 这样流行的 BI 工具不支持对 ENUM 进行过滤,但是,它们可以在 TEXT 列上正常工作。

答案 5 :(得分:-1)

重点是,如果允许应用程序执行DDL,则它们更有可能导致阻塞或冲突。 DDL最好离线完成,即在单用户模式下。