如何在 PostgreSQL 中为数组的元素创建索引?

cc *_*ung 3 sql arrays postgresql indexing

使用此架构:

create table object (
   obj_id      serial      primary key,
   name        varchar(80) not null unique,
   description text,
   tag_arr     int[]
);

create table tag (
   tag_id      serial      primary key,
   label       varchar(20) not null unique
);
Run Code Online (Sandbox Code Playgroud)

一个对象可以附加任意数量的标签。object X tag我希望将tag_ids保留在一个数组中,而不是一个表,以便可以轻松地使用对象记录获取它们。

如何创建索引object以便每个元素tar_arr都是一个索引?

也就是说,有没有更好的方法来解决这个问题?

讨论

这可以通过以下方式实现:

create table obj_x_tag(
   obj_id    references object,
   tag_id    references tag,
   constraint obj_x_tag_pk primary key( obj_id, tag_id )
);

select obj_id, name, description, array_agg( tag_id )
from object o
join obj_x_tag x using( obj_id )
group by 1, 2;
Run Code Online (Sandbox Code Playgroud)

但对我来说,简单地将tag_ids数组保留在一列中并省去交叉表和array_agg()

建议使用PostgresQL SQL: Converting results to array。如前所述,问题在于“这实际上并不索引单个数组值,而是索引整个数组”

还建议使用 pgintarrgist(或gin)索引。问题-我-看来,指数是基于标准的设置PG阵列运营商,不是寻找一定的优化一个数组的元素,而是其中一个阵列包含另一个相交与另一-对我来说这是反直觉也就是说,在规模和速度方面,如此广泛的解决方案对于如此狭窄的问题是正确的。此外,intarr扩展似乎仅限于int,不包括int64char,限制了它的实用性。

Erw*_*ter 6

您可以使用标准 Postgres 在任何一维数组上创建 GIN 索引。
此处的手册中的详细信息(最后一章)。

在使用integer数组(plain int4、notint2int8noNULL值)进行操作时,额外提供的模块intarray提供了更多的运算符和通常的卓越性能。安装它(每个数据库一次):

CREATE EXTENSION intarray;
Run Code Online (Sandbox Code Playgroud)

您可以在整数数组上创建 GIN 或 GIST 索引。手册中示例。
CREATE EXTENSION需要 PostgreSQL 9.1 或更高版本。对于旧版本,您需要运行提供的脚本。