如何在Postgres中执行批量标签更新操作?

时间:2017-07-11 23:33:21

标签: postgresql jsonb hstore

我的Postgres 9.6数据库中有一个包含标签的表。我希望这些标签存储在一个列中,而不是标准化为单独的标签表。

我需要能够执行批量标签更新;例如“update things add tag1,tag2,tag3”或“update things remove tag1,tag2,tag3”。我正在努力制定这些查询。最好的方法是什么?

我使用不同的列类型执行了一些实验来表示标记:

列类型JSONB,存储数组

从编程角度来看,这似乎非常自然,并且可以轻松映射到我的实体模型中的Set对象。但Postgres似乎没有一个可以删除多个标签的运算符:

select '["tag1", "tag2"]'::jsonb - 'tag1';            -- works
select '["tag1", "tag2"]'::jsonb - '["tag1"]'::jsonb; -- doesn't work

另外,我如何执行重复删除的联合?

select '["tag1", "tag2"]'::jsonb || '["tag2", "tag3"]'; -- tag2 twice!

列类型TEXT []

这似乎与JSONB数组有着相同的问题。我没有看到“设置差异”或“设置联合”功能。但也许有一种创建这些功能的方法?

列类型HSTORE

以{“key”=> true}或其他一些被忽略的值存储,只测试密钥存在。这实际上似乎有效;密钥有联合和差异运算符:

select '"tag1" => true, "tag2" => true' - '"tag1" => true, "tag2" => true'; -- works!
select '"tag1" => true, "tag2" => true' || '"tag2" => true, "tag3" => true'; -- works, no dupes!

对于我的ORM来说,这是一个温和的PITA,在查询中始终使用akeys / skeys函数会有点烦人。但至少我的批量更新查询很简单。

另外,如果有人为JSONB数组或文本数组找出差异/联合函数,那么HSTORE的批量更新是否会表现得更好?

列类型JSONB,存储对象

我想也许类似HSTORE的方法(例如{keyname: true})可以和JSONB一起使用,但是我没有看到一组类似于union和difference的函数/运算符。使用ORM进行映射也是一种轻微的麻烦。我想在HSTORE上更喜欢这个的唯一原因是我担心HSTORE有一天会被放弃,但是JSONB缺乏相同的功能。

我该怎么办?有没有为JSONB或TEXT []类型制作联合/差异运算符的好方法?或者我应该回到HSTORE?

0 个答案:

没有答案