我们说我有一张名为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中有一种优雅的方式吗?编写一个函数来完成这个是否有意义?
答案 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)
我建议将unnest
和join
组合使用。
即。形式的东西:
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;