PostgreSQL 以逗号或整数数组分隔的整数列表以提高性能?

Fab*_*oni 7 postgresql array

根据主题,我有一个 varchar 字段,我在其中存储一些用逗号分隔的数字。该列表根据客户的选择增长和缩小。然后我在查询中使用它来检查特定值是否在该列表中

value || ','
Run Code Online (Sandbox Code Playgroud)

它运行良好,但正在考虑将其转换为整数数组。

这在技术/性能方式和正确编程数据库方面是否是更好的解决方案?

Cra*_*ger 13

最好的方法很可能是sometable(main_id, value)(main_id, value). 这允许非常快速的查找来查看“对于这个 mainid,这个值是否存在”。这将让您强制执行外键关系。除非您有充分的理由,否则请使用这种传统的关系方法。

否则,您可以并且应该使用数组字段而不是逗号分隔的列表。从设计的角度来看,使用逗号分隔的列表是非常可怕的。它使查询更难编写,更容易出错,并迫使您只为简单的操作进行大量缓慢且低效的字符串操作和数字解析,并在没有非常低效的CHECK约束或触发器的情况下阻止任何类型的完整性检查。我认为比尔把它钉在了:

1,2,3,香蕉,5

对于数组,您可以使用intarray扩展来提供 GiST 索引,让您可以使用可索引或操作快速测试数组是否包含给定值。您可能要添加扩展,所以你可以创建一个综合的GiST指数,如果你的查询通常的形式是:@><@btree_gistmain_id, the_values_array

WHERE main_id = blah AND the_values_array @> ARRAY[42]
Run Code Online (Sandbox Code Playgroud)

(或者有两个单独的索引,看看它是否会进行位图索引扫描)。

您还不能在 PostgreSQL 中将外键关系强制执行到数组中,尽管该功能似乎即将推出。同时,您需要使用一些复杂的触发器来执行此操作。不过,这是一个很多比一个逗号分隔的列表更好。

  • +1 带有逗号分隔列表的字符串唯一可以接受的情况是您*总是* 将列表本身视为原子数据元素。即,您永远不需要使用 SQL 语义搜索、排序或获取单个元素。 (3认同)