实例说明PostgreSQL中如何使用jsonb

来自yinmingjun,引用请注明!

 

 PostgreSQL对jsonb支持的概要说明

如何理解PostgreSQL的jsonb的支持呢?下面的案例给出了答案。

 

先从机制上说明一下,PostgreSQL中jsonb是按文本存储,在处理的时候解析,所以分存储解析两个阶段!

SQL的输入输出的阶段,和jsonb的存储阶段等同,都是作为未解析的数据来处理。

 

对于PostgreSQL来说,在SQL层面只存在jsonb一个类型,而jsonb的内部(解析json层面),存在不同的数据类型,包括: string, number, object, array等。在SQL的输入输出层面上,只能是通过jsonb来传输,jsonb可以理解为一个字符串,其内容符合json解析规则。可以简单的将jsonb强制转换为varchar或text,来获取符合json格式的文本。

 

但是,在很多时候,是需要提取json中的值,这个是数据处理时最多的场景。PostgreSQL允许这种提取,返回SQL的varchar,比如通过 ->>#>>,这种操作和获取的jsonb直接转换成varchar的差异在于,抹平了不同类型输出的差异。

 

比如,如果json的'a'字段的值,有一些对应数值8, 有一些对应字符串"8",有一些对应数值8.0,有一些对应字符串"8.0",这种情况,通过 ->> 返回的就是对应json值直接做str(a)之后的结果,返回:8, 8, 8.0, 8.0,比较容易做后续的加工处理。如果将json值直接转varchar,就会变成: 8, "8", 8.0, "8.0",后续统一处理的难度增加了很多,因此,在数据处理层面,->> 简化了数值处理的难度。

 

因此,理解 ->> 和 #>> 的作用,可以看做在json内部的解析上,对提取的字段值做了str(a)的操作,并强制统一返回对应的字符串字面量,并转化成SQL的varchar!!!

 

jsonb测试案例

 

1)jsonb的值提取

 

查询json中的字符串类型:

SELECT ('{"book": 50, "edition": "8"}'::jsonb->'edition');

返回jsonb类型,值为"8",是字符串的json表示:

通过jsonb_typeof查询返回的json对应的数据类型,是将返回做json解析,并做类型推断:

SELECT jsonb_typeof('{"book": 50, "edition": "8"}'::jsonb->'edition');

返回:

2)查询jsonb中不存在的字段

查询不存在的字段,返回json对应的null:

SELECT '{"book": 50, "edition": "8"}'::jsonb->'NG';

返回json对应的null:

探测json对应的null的类型,还是null:

SELECT jsonb_typeof('{"book": 50, "edition": "8"}'::jsonb->'NG');

返回:

不存在的字段的null值和db的null等同。

如:

SELECT '{"book": 50, "edition": "8"}'::jsonb->'NG' is null;

返回:

探测返回的json数值的类型:

SELECT jsonb_typeof('{"book": 50, "edition": "8"}'::jsonb->'book');

返回:

3)jsonb中 -> 和 ->>的差异

对应jsonb中,返回的不同类型的差异,可以通过 ->> 强制转换成 varchar 来抹平!!!

例:

select js->'book', js->'edition', js->'bucket', js->'NG'
from (
    SELECT '{
      "book": 50,
      "edition": "8",
      "bucket":10.0
    }'::jsonb as js
) a;

返回:

可以替换为:

select js->>'book', js->>'edition', js->>'bucket', js->>'NG'
from (
    SELECT '{
      "book": 50,
      "edition": "8",
      "bucket":10.0
    }'::jsonb as js
) a;

返回:

因为 ->> 对应的类型都是db类型中的varchar(与jsonb脱钩),很容易通过postgresql提供的类型转换函数做对应的处理。

例如:

select (js->>'bucket')::float = 10
from (
    SELECT '{
      "book": 50,
      "edition": "8",
      "bucket":10.0
    }'::jsonb as js
) a;

返回:

4)jsonb中字段为object的情况

验证->和->>对obj类型的作用,可以看:

select js->'obj'
from (
    SELECT '{
      "book": 50,
      "edition": "8",
      "bucket":10.0,
      "obj": {
        "a": 1,
        "b": 2
      }
    }'::jsonb as js
) a;

返回:

再看这个:

select js->>'obj'
from (
    SELECT '{
      "book": 50,
      "edition": "8",
      "bucket":10.0,
      "obj": {
        "a": 1,
        "b": 2
      }
    }'::jsonb as js
) a;

返回:

差别在于,一个是jsonb,另外一个是varchar!

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值