在我工作的地方,我们使用postgres数据库(8.3很快就会迁移到8.4)。目前关于在数据库中使用枚举的争论很少。我个人不喜欢db enum类型。除此之外,它还将应用程序逻辑放在数据库中,并为代码和数据之间的不匹配创建了可能性。
我想知道postgres枚举的优点究竟是什么(除了可读性之外)还有什么不妥之处?
答案 0 :(得分:33)
枚举的优点是:
缺点是:
答案 1 :(得分:3)
Enums结合了int的优点和字符串的优点:它们像int一样小而快,像字符串一样可读,还具有安全的附加优点(你不能错误地拼写枚举)。
但是,如果你不关心可读性,那么int就像枚举一样好。
答案 2 :(得分:0)
作为优势,您还有DB检查,没有其他枚举值无法记录在列中。对我来说最大的缺点是,枚举只能通过增加值来修改,但是自Postgres 9.1以来它已经过去了:https://stackoverflow.com/a/7834949/548473
答案 3 :(得分:0)
减少存储:当定义了 255 个或更少的 ENUM 元素时,Postgres 每个元组仅使用 1 个字节,或者为 256~65535 个元素使用 2 个字节。这是因为 Postgres 不是存储值的常量文字,而是将索引存储在该值的有序集合中。对于非常大的表,这可能会显着节省存储空间。
任意排序:
CREATE TABLE opening_hours(
week_day ENUM ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
opening_time TIME,
closing_time TIME
);
如果您按week_day排序,它将按照您指定的顺序进行排序,这在上述情况下很方便。
答案 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最好离线完成,即在单用户模式下。