Postgresql——jsonb类型

Postgresql Json

最近有个功能,需要用到 NoSQL 数据库。但是又不想因为这个小小的功能给系统增加一个 MongoDB 数据库,于是就想到了 Postgresql 支持 JSON 类型的数据格式,可以用来实现类似 NoSQL 数据库的功能。于是研究了一下。

版本说明:

Postgresql Version : 12

Linux Virtual Machine: Ubuntu 22.04 4G 2Cpu

数据类型

JSON 和 JSONB 区别

Postgresql 从 9.2 版本开始支持 json 数据类型,从 9.4 开始支持 jsonb 数据类型。

区别:

  • json 类型是将整个json字符进行完成保存,包括空格、重复的键、和键的顺序等。
  • jsonb 类型会对json字符进行解析后保存二进制,解析的时候会删除不必要的空格和重复的键等。

由于上面的区别,所以在储存的时候 json 会比 jsonb 快,毕竟少了一个解析的步骤。但是在查询的时候 json 会比 jsonb 慢。

由于 jsonb 是格式化后的数据,所以他能使用的函数比 json 多很多,jsonb 甚至能使用索引。(具体使用哪种类型就要根据具体的业务场景了)

注意:这两者在储存的时候,字符串都要符合json规范,要不会储存失败。

JSON 和 JSONB 测试

创建一个表格,实验一下。

-- 创建一个 json_test_table 表 
-- json_data 是 josn 类型
-- jsonb_data 是 jsonb 类型

CREATE TABLE "json_test_table" (
  "id" int4 PRIMARY KEY,
  "json_data" json,
  "jsonb_data" jsonb
)

向表里插入一条数据

-- 这里注意一下两个 json 对象都有一个相同的键'name'。

INSERT INTO 
	json_test_table(id,json_data,jsonb_data)
VALUES(
	1,
	'{
		"name":"zhangsan",
		"name":"zhangsan",
		"age":18,
		"isBoy":true	
	}
	'::json,
	'
	{
		"name":"lisi",
		"name":"lisi1",
		"age":22,
		"isBoy":false	
	}
	'::jsonb
)

把刚才的数据查出来

SELECT * FROM json_test_table 
id | json_data                                                    |  jsonb_data
--------------------------------------------------------------------------------------------------------------
1  | {"name":"zhangsan","name":"zhangsan","age":18,"isBoy":true	} | {"age": 22, "name": "lisi1", "isBoy": false}

查询结果中 jsonb_data 中只保留了一个 name 并且键的顺序也改变了(这里没体现出来json_data也保留了空格等字符,可以自己写个sql测一下)。

使用 JSONB 类型

由于本次功能读多写少,所以这里主要研究一下 jsonb 的增删改查的功能,其实 josn 类型也差不多。

增加

新增一条 josnb_data 就使用普通的 insert sql 就行。

INSERT INTO 
	json_test_table(id,jsonb_data)
VALUES(
	2,
	'
	{
		"name":"lisi",
		"age":22,
		"isBoy":false	
	}
	'
)

上面我们在表中新增了行数据,现在再往 jsonb_data 中再新增一个键 "address_path" 他是一个字符串数组,值为 ["中国","江苏"]

-- 其实这里只是调用 jsonb_set 方法把 jsonb 修改后,一个 UPDATE 操作把数据更新了。

UPDATE 
  json_test_table
SET 
  jsonb_data = jsonb_set(jsonb_data, '{address_path}', '["中国","江苏"]')
WHERE 
  id = 2

更新后数据变成了

id |  jsonb_data
--------------------------------------------------------------------------------------------------------------
1  |  {"age": 22, "name": "lisi", "isBoy": false, "address_path": ["中国", "江苏"]}

jsonb_set ( target, path, new_value [, create_if_missing ] )

  • target:需要修改的json数据。
  • path:要修改的值的路径。如果target是数组'{0,a}'表示在下标是0的位置更新a属性,如果是对象,则写'{a}'则会修改"a"键的内容。
  • create_if_missing:当不存在 path 指定的键是否新建一个,默认是 true。

本质上对 jsonb 的增删改等操作就是 UPDATE 语句把表中的原数据更新掉。只是对 jsonb 对象的修改交给了数据库,这样压力就给到数据库服务。你完全可以把整条数据查出来,然后用业务逻辑处理后再调用 UPDATE 回去,但是这样压力就到了业务服务上,而且每次数据传输也会消耗时间。

除了使用上面的 jsonb_set 也可以使用 || 操作符。

UPDATE 
  json_test_table
SET 
  jsonb_data = jsonb_data || '{"address_path":["中国","江苏"]}'
WHERE 
  id = 2

查找

查找某个键的值

如果我们不想把整个 jsonb_data 都查出来,只想查找其中某几个键值。

SELECT jsonb_data::json ->> 'name',jsonb_data::json ->> 'age' as ageFROM json_test_table WHERE id = 2

返回

name | age |
------------
lisi | 22  |

如果是数组的对象应该怎么查呢?

我们在添加一列用于测试数组

id |  jsonb_arr_data 
--------------------------------------------------------------------------------------------------------------
2  |  [{"id": 1, "value": "value1"}, {"id": 2, "value": "value2"}, {"id": 3, "value": "value3"}]

先来看一下一个方法 jsonb_array_elements 。他的作用就是 JSON数组展开为一组JSON值.

SELECT jsonb_array_elements(jsonb_arr_data) FROM json_test_table WHERE id = 2
jsonb_array_elements        |
----------------------------
{"id": 1, "value": "value1"}|
{"id": 2, "value": "value2"}|
{"id": 3, "value": "value3"}|

所以只想查出 id 是 1 的值可以这么写

SELECT D FROM json_test_table T,jsonb_array_elements(jsonb_arr_data) D WHERE id = 2 AND D::json ->> 'id' = '1'
d                           |
----------------------------
{"id": 1, "value": "value1"}|

所以只想查出 id 是 1 和 2 的值可以这么写


SELECT D FROM json_test_table T,jsonb_array_elements(jsonb_arr_data) D WHERE id = 2 AND D::json ->> 'id' in ('1','2')
d                           |
----------------------------
{"id": 1, "value": "value1"}|
{"id": 2, "value": "value2"}|

删除

删除刚才添加的 "address_path"

UPDATE 
  json_test_table
SET 
  jsonb_data = jsonb_data - 'address_path'
WHERE 
  id = 2

参考

Postgresql Release 9.2,by postgresql.org
Postgresql Release 9.4,by postgresql.org
Postgresql JSON Functions and Operators,by postgresql.org
PostgreSQL JSON 函数和操作符,by w3cschool.cn

作者:chenghd

出处:https://www.cnblogs.com/chenghd/p/17320879.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   CHENGHD  阅读(2780)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示

目录导航