PostgreSQL - 整数 [] 最佳实践
Posted
技术标签:
【中文标题】PostgreSQL - 整数 [] 最佳实践【英文标题】:PostgreSQL - integer[] best practice 【发布时间】:2011-01-25 18:20:15 【问题描述】:最近我在开发一个网络应用程序,我决定在数据模型中使用 integer[]。有 2 个表,一个带有文章数据,另一个带有标签(标签 ID 和描述),决定了文章将在 article.tags integer[] 列中标记的标签 ID。
正如Milen A. Radev 指出的那样:
提示:数组不是集合;搜索特定的数组元素可能是数据库设计错误的标志。考虑使用一个单独的表,其中每个项目将是一个数组元素。这将更容易搜索,并且对于大量元素可能会更好地扩展。
不仅如此,结果还必须使用 JDBC 和 iBatis 处理 integer[],我应该说“有趣”。
目前,我可以摆脱我必须做的工作实施。为简单起见,它可能会使用存储 article.id 和 tag.id 关系的单独表进行重新设计。
最后我对 integer[] 最适合什么以及在什么情况下使用感到困惑?
我想我很难弄清楚它不适合什么。
【问题讨论】:
【参考方案1】:在处理诸如注释线程之类的树结构时,我在 PostgreSQL 中使用了数组。您可以将从根到节点的路径存储为分支编号数组。然后,以正确的显示顺序拉出整棵树就很简单了:
SELECT stuff
FROM comments
WHERE thread = X
ORDER BY path -- This would be the array.
PostgreSQL 以唯一合理的方式比较数组。使用数组作为从根开始的路径还为您提供了一种计算节点深度的简单方法。您可以使用一个字符串(每个分支编号使用 3 个 base-96 位)和 ASCII-betical 排序来实现相同的目的,但数组更清晰。
是的,还有其他处理树的方法更正确,但使用数组提供了非常清晰的实现。如果我要进行大量的树操作,那么维护路径数组将涉及很多繁忙的工作,因此我可能会采用不同的表示。
并非完全特定于 Java,但在某些情况下,数组是手头数据的一种自然且有用的表示(即使在 SQL 中)。
【讨论】:
很棒的例子。【参考方案2】:恕我直言,由于任何数组都违反了 1NF,因此最好的上下文是:...(drumroll).....无。
这就涉及到为什么我们会有不打算查询的数据的问题。所有值都可能是可搜索的,如果我们不应该在可搜索的值上使用数组,我们会再次得出结论,它永远不值得使用。
这仅留下一个假设情况,即您存储数组仅用于在客户端上进行分析和操作。我确信这些存在,但在我的经验中不存在。
编辑:上面我说过,“我确定这些存在......”看看@mu 的答案太短了。
【讨论】:
【参考方案3】:我能想到三个应用:
第一个是非规范化。权衡包括: 您不能轻松地单独更新或处理元素。但是一次获取所有这些内容既简单又快捷。它还节省了很多空间。
第二个稍微相关的是,您使用数组不是用于存储,而是用于一些中间处理。例如,如果您想用一种无法轻松处理正确集合的非 SQL 语言批量处理数据。
第三个是用于存储有序的数据列表。我遇到过一些这样的应用程序,但很难说清楚。当然,您也可以在带有额外列的表中表示该位置,但有时这没有多大意义,因为您不需要单独访问数据库中的各个部分。在某些情况下,这只是客户端应用程序想要存储和稍后检索的列表。
但你的整体感觉是对的。如果您不了解,您的第一直觉可能应该是不要使用数组。
【讨论】:
【参考方案4】:如果数组作为一个整体是一个值,我可能会考虑使用数组数据类型。但是什么时候数组只是一个整体的值呢?我真的不知道。
也许当它仅 更有意义地搜索整个值。在您想知道相应行之前,拥有一个应该包含您正在搜索的项目的表似乎没有多大意义。所以如果你想搜索完整的数组作为key。
【讨论】:
【参考方案5】:integer[] 对转换表很有用。其中键是索引,并且已知每个索引都有一个值,或者以某种方式表示空位置(如-1)。我认为在这种情况下它会比外键更快。
另一种用途是图表。每次测试运行的结果是什么。测试运行有 6 个结果。是一行,integer[] 是 6 个结果的数组。
【讨论】:
以上是关于PostgreSQL - 整数 [] 最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
Django:将项目从 sqlite 迁移到 PostgreSQL 的最佳实践是啥
PostgreSQL 9.5 - 行级安全/ROLE 最佳实践
入门教程SequoiaDB+PostgreSQL数据实时检索最佳实践