PostgreSQL jsonb 数组的增删改查

爱被打了一巴掌 2022-10-16 12:27 354阅读 0赞

有时候我们需要使用PostgreSQL这种结构化数据库来存储一些非结构化数据,PostgreSQL恰好又提供了json这种数据类型,这里我们来简单介绍使用jsonb的一些常见操作。

PostgreSQL 提供了 json和 jsonb两种 json类型,两者的主要区别就是,json查询相对慢一些,插入会快一点,而jsonb则相反,查询效率会高一点,插入会慢一点。

下面进入我们今天的正题

表结构

  1. create table purchase_order
  2. (
  3. id serial not null primary key,
  4. tag jsonb
  5. )

数据也是非常简单

  1. INSERT INTO plutus.purchase_order (id, tag) VALUES (4787, '[{"uid": 1, "name": "标签名1", "add_time": "2021-05-29 17:00:00"}, {"uid": 2, "name": "标签名2", "add_time": "2021-05-29 17:00:00"}]');

重点是tag

  1. [{
  2. "uid": 1,
  3. "name": "标签名1",
  4. "add_time": "2021-05-29 17:00:00"
  5. }, {
  6. "uid": 2,
  7. "name": "标签名2",
  8. "add_time": "2021-05-29 17:00:00"
  9. }]

操作

这里来实现一些简单的操作

条件查询

我们查询 id = 4787 且 json 中 uid = 1 的tag

  1. -- 嵌套子查询
  2. select * from (
  3. select jsonb_array_elements(tag) as tt from purchase_order where id = 4787) a
  4. where tt -> 'uid' = '1';
  5. -- 或者这种方式
  6. SELECT
  7. id,r
  8. FROM
  9. purchase_order s, jsonb_array_elements(s.tag) r
  10. WHERE
  11. s.id = 4787 and r->>'uid' = '2' ;

查询结果
在这里插入图片描述
如果仅仅是查询json中包含 uid = 3的结果可以像这样查询

  1. SELECT tag FROM purchase_order
  2. WHERE id = 4787 and tag @> '[{"uid": 3}]';

新增

新增也比较简单,我们在原有的json上在增加个对象。
原先的json对象是这样的

  1. [{
  2. "uid": 1,
  3. "name": "标签名1",
  4. "add_time": "2021-05-29 17:00:00"
  5. }, {
  6. "uid": 2,
  7. "name": "标签名2",
  8. "add_time": "2021-05-29 17:00:00"
  9. }]

执行如下语句

  1. UPDATE purchase_order SET tag = tag || '[{ "uid": 3, "name": "标签名3", "add_time": "2021-05-29 17:00:00" }]' where id = 4787;

再查询

  1. [{
  2. "uid": 1,
  3. "name": "标签名1",
  4. "add_time": "2021-05-29 17:00:00"
  5. }, {
  6. "uid": 2,
  7. "name": "标签名2",
  8. "add_time": "2021-05-29 17:00:00"
  9. }, {
  10. "uid": 3,
  11. "name": "标签名3",
  12. "add_time": "2021-05-29 17:00:00"
  13. }]

删除

如果我要删除上面 uid 为3的值,使用如下sql即可

  1. UPDATE purchase_order
  2. SET tag = t.js_new
  3. FROM
  4. (
  5. SELECT jsonb_agg( (tag ->> ( idx-1 )::int)::jsonb ) AS js_new
  6. FROM purchase_order
  7. CROSS JOIN jsonb_array_elements(tag)
  8. WITH ORDINALITY arr(j,idx)
  9. WHERE j->>'uid' NOT IN ('3')
  10. ) t;

再次查询
在这里插入图片描述

修改

我们现在要把 id = 4787
name = '标签名1'
的修改为name = '标签new'

sql 如下

  1. UPDATE purchase_order AS g
  2. SET tag = REPLACE(tag::text, '"name": "标签名1"','"name": "标签new"')::json
  3. WHERE g.tag IN ( SELECT g.tag
  4. FROM purchase_order AS g
  5. CROSS JOIN jsonb_array_elements(g.tag) AS j
  6. WHERE id = 4787 and j ->>'uid' = '1' )

总结

其实还有很多其他方式去实现,但是总体来说修改删除都不是特别方便和好维护,建议修改删除的时候直接当做字符串去全量更新即可,这样好维护一点。

另外附带一份官方的 jsonb 操作文档连接给大家自己去查阅吧
链接
注意文档选择合适的版本哦

发表评论

表情:
评论列表 (有 0 条评论,354人围观)

还没有评论,来说两句吧...

相关阅读