使用这个模式:
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
);
一个对象可以附加任意数量的标签。我希望用一个数组来保存tag_id,而不是使用一个
object X tag
表,以便可以轻松地通过对象记录获取它们。如何在
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;
但对我来说,仅仅将tag_id
数组保留在一列中,并且放弃交叉表和array_agg()
更加合理。
建议使用PostgresQL SQL: Converting results to array。问题在于,正如所指出的那样,“这实际上并没有索引单个数组值,而是对整个数组进行索引”。
还有人建议使用pg的intarr
和gist
(或gin
)索引。对我而言,问题似乎在于该索引是为标准的pg基于集合的数组运算符而设计的,而不是为了优化查找数组中的一个元素,而是其中一个数组包含另一个数组,与另一个数组相交 - 对我来说,这种宽泛的解决方案对于如此狭窄的问题来说,在大小和速度上都不正确。另外,intarr
扩展似乎只限于int
,而不涵盖int64
或char
,从而限制了其有用性。