为元素的存在和唯一性索引Postgresql JSONB数组

问题描述

我有一个名为posts的Postgresql 11.8表,我想在其中定义JSONB类型的列slugs,其中将包含诸如["my-first-post","another-slug-for-my-first-post"]之类的字符串数组。

我可以使用?存在运算符SELECT * FROM posts WHERE slugs ? 'some-slug'找到具有特定子句的帖子。

每个帖子预计只有少数几个,但是帖子的数量有望增长。

考虑以上查询,其中some-slug可以是任何字符串:

  • 如何定义索引以进行合理的查询(不进行全表扫描)?
  • 如何确保同一个子弹不能多次出现(在不同阵列中以及在不同阵列中)?

我主要是在寻找Postgresql 11的解决方案,但也希望了解将来版本中的解决方案。

数据库在Rails 6.0应用程序中使用,因此我对Rails迁移语法也很感兴趣。

解决方法

您可以在?列上使用常规GIN索引来支持jsonb运算符。

但是,您不能强制数组值唯一。

尤其是如果您希望具有数据库约束,则应该使用JSON为数据建模。使用带有多个表和外键的常规规范化数据模型,可以轻松实现这种唯一性约束。