使用Postgres进行整数数组查找

时间:2014-05-07 04:07:38

标签: postgresql postgresql-9.3

我们说我有一张名为tag的表格:

CREATE TABLE tag (
  id SERIAL PRIMARY KEY,
  text TEXT NOT NULL UNIQUE
);

我在其他表上使用整数数组来引用这些标记:

CREATE TABLE device (
  id SERIAL PRIMARY KEY,
  tag_ids INTEGER[] NOT NULL DEFAULT '{}',
);

我可以将tag_ids映射到tag中的相应行的最简单,最有效的方法是什么,以便我可以查询device表,结果将包含{ {1}}列中包含文本数组中每个标记的tags

据我所知,这不是首选技术,并且有许多明显的缺点。我知道没有办法在数组中强制引用完整性。我知道多对多连接会更简单,也可能是实现标记的更好方法。

除了数据库规范化讲座之外,在postgres中有一种优雅的方式吗?编写一个函数来完成这个是否有意义?

2 个答案:

答案 0 :(得分:1)

未经测试,但是IIRC:

SELECT 
    device.*, t."text"
FROM 
    device d
    left outer join tag t on ( ARRAY[t.id] @> d.tag_ids)

应该能够在d.tag_ids上使用GiST或GIN索引。这对于您想要“查找包含tag [x]”的行的查询也很有用。

我可能会让@>操作符的方向错误,我总是把它弄糊涂了。有关详细信息,请参阅数组运算符文档。

intarray模块为我推荐使用的整数数组提供了一个gist opclass;它更紧凑,更新更快。

答案 1 :(得分:0)

我建议将unnestjoin组合使用。

即。形式的东西:

select unnest(t.tag_ids) as tag_id, d.*
from device as d
join tag as t ON (d.tag_id = d.id)
order by d.tag_id;