暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

突破关系型边界:PostgreSQL 的 JSON 如何重新定义数据敏捷性

前言

在本文中,我们将讨论 PostgreSQL 如何实现和处理 JSON 对象。读者需要具备一定的 Linux、Postgres 和 JSON 的基础知识,因为我们不仅会介绍这些新特性,还会讲解如何实现它们。本文是基于运行在 Ubuntu 23.04 上的 PostgreSQL 16(开发版本)撰写的。首先,我将简要回顾一下 JSON 的背景,然后讲解如何在 Postgres 中使用 JSON,最后介绍一些可以用来与 JSON对象交互的有用函数。

背景

JSON(JavaScript 对象表示法)是一种采用键值对存储信息的开放标准文件格式。这种轻量级且与编程语言无关的格式具有两大优势:既便于人工阅读,又易于机器生成和解析。其核心价值在于实现了应用程序间的无缝互操作性,这也正是它能够成为通用数据存储格式的关键原因。

这种特性尤其适合 Web 应用场景——当不同程序需要相互通信时,往往面临实现语言各异的情况。只要每个程序都具备解析 JSON 文件的能力,无论对方使用何种软件或硬件系统,双方都能实现有效通信。既然 JSON 在数据存储方面如此出色,接下来我们就探讨如何将其融入 PostgreSQL 数据库体系。

使用 JSON

PostgreSQL 有两种数据类型用于在表中存储 JSON 数据,分别是json
jsonb
json
类型将 JSON 数据作为字符串存储,因此当数据被读取时,接收的应用程序需要将文本转换回 JSON 对象。另一方面,jsonb
类型直接将 JSON 对象作为二进制表示存储。当我们将 JSON 对象存储为jsonb
时,PostgreSQL 将 JSON 类型映射为其自己的数据类型,具体如下表所示:

JSON 原始类型
PostgreSQL 类型
说明
string
text
不允许使用\u0000
,Unicode 转义表示不可在数据库编码中找到的字符
number
numeric
不允许 NaN 和无穷大值
boolean
boolean
只接受小写的true
false
null
(none)
SQL NULL 是一个不同的概念

虽然两种 JSON 数据类型接受的输入几乎完全相同,但由于jsonb
类型在效率上的显著优势,大多数应用场景更适合选用jsonb
格式。因此,本文的示例将主要聚焦于jsonb
类型的使用。

要在 PostgreSQL 中使用 JSON 功能,首先需要创建包含 JSON 类型字段的数据表。# CREATE TABLE t1 (id int, data jsonb);

现在我们可以插入一些数据。# INSERT INTO t1 VALUES (1, '{"a":1, "b":"hello", "c":{"d":"world","e":2},"arr":[1,2,3]}');

让我们看看这些数据是如何呈现的。# SELECT * FROM t1;
 id |                     data
----+-----------------------------------------------
  1 | {"a":1, "b":"hello", "c":{"d":"world","e":2},"arr":[1,2,3]}
(1 row)

PostgreSQL 不仅能够存储 JSON 对象,更提供了一系列专属函数,可直接在查询中以键值对作为参数进行数据交互。下面我们通过具体示例来演示其实现方式。

JSON 函数

运算符

PostgreSQL 为实现 JSON 对象元素访问提供了一系列专用操作符。这些操作符在官方文档中的功能概要如下:

运算符
右操作数类型
描述
->
int
获取 JSON 数组元素
->
text
获取 JSON 对象字段
->>
int
获取 JSON 数组元素(作为文本)
->>
text
获取 JSON 对象字段(作为文本)
#>
array of text
获取指定路径的 JSON 对象
#>>
array of text
获取指定路径的 JSON 对象(作为文本)

使用这些运算符,我们可以从之前插入的 JSON 对象中访问元素。这些运算符返回的值如下所示:# SELECT data->'a' AS result FROM t1;
 result
--------
 1
(1 row)

# SELECT data->'arr'->2 AS result FROM t1;
 result
--------
 3
(1 row)

现在我们已经能够访问这些值,便可以直接在表查询中使用它们来筛选数据行。# INSERT INTO t1 VALUES (1,'{"num":12,"arr":[1,2,3]}'),(2,'{"num":14,"arr":[4,5,6]}'),(3,'{"num":16,"arr":[7,8,9]}');
# SELECT data FROM t1 WHERE (data->'arr'->1)::integer >= 5;
          result
--------------------------
 {"num":14,"arr":[4,5,6]}
 {"num":16,"arr":[7,8,9]}
(2 rows)

如结果所示,系统仅筛选出 JSON 对象中 "arr" 键对应数组的第二个元素大于或等于 5 的数据行。

下标

这些 JSON 对象还支持像许多编程语言一样的下标操作。在 Postgres 中,我们可以将上面的运算符转换为下标操作,如下所示:# SELECT data FROM t1 WHERE (data['arr'][1])::integer >= 5;
             data
-------------------------------
 {"arr": [4, 5, 6], "num": 14}
 {"arr": [7, 8, 9], "num": 16}
(2 rows)

与之前一样,我们也可以在SELECT
语句中使用下标:# SELECT data['num'] FROM t1 WHERE (data['arr'][1])::integer >= 5;
 data
------
 14
 16
(2 rows)

对于熟悉 JSON 开发的用户而言,此语法结构可能更为亲切。两种调用方式可任选其一,它们的功能实现基本一致——既支持文本格式的键名输入,也兼容整数形式的数组索引访问。

函数

PostgreSQL 还提供了一系列更强大的函数,用于实现 JSON 对象的数据转换、信息检索(如大小计算、键名提取及遍历操作)。与前述功能一致,这些函数均可直接嵌入查询语句中使用,从而充分发挥 JSON 在数据库中的强大功能。以下是我们演示 JSON 函数时将用到的表结构和示例数据:# CREATE TABLE myjson (id int, data jsonb);
# INSERT INTO myjson VALUES(1,'{"mynum":1,"mytext":"hello","myarr":[1,2,3,4,5]}');

更多的函数可以在 PostgreSQL 文档[1]的表 9.41 中找到。这里我们将简要介绍一些常见的函数。

array_to_json

将任意 SQL 值转换为 JSON 二进制类型。SELECT to_jsonb(data['myarr']) FROM myjson;
    to_jsonb
-----------------
 [1, 2, 3, 4, 5]
(1 row)

jsonb_array_length

返回 JSON 二进制数组中元素的数量。SELECT jsonb_array_length(data['myarr']) FROM myjson;
 jsonb_array_length
--------------------
                  5
(1 row)

jsonb_each

将顶层 JSON 对象转换为键值对形式。SELECT jsonb_each(dataFROM myjson;
        jsonb_each
---------------------------
 (myarr,"[1, 2, 3, 4, 5]")
 (mynum,1)
 (mytext,"""hello""")

jsonb_object_keys

返回 JSON 二进制对象的键。SELECT jsonb_object_keys(dataFROM myjson;
 jsonb_object_keys
-------------------
 myarr
 mynum
 mytext
(3 rows)

结论

在本文中,我们了解了 PostgreSQL 的 JSON 数据类型及其如何用于存储、访问和管理 JSON 对象。首先,我们回顾了 JSON 格式及其在 Web 中的有用性。然后,我们看了如何设置一个表来使用 JSON 数据类型,并介绍了不同的访问方法。最后,我们展示了一小部分 JSON 对象可以使用的函数,并说明了它们在查询中实现时的实用性。

JSON 数据类型是一个非常灵活且具有广泛互操作性的对象,许多 Web API 接口都能理解它。如果您的数据库需要与任何类型的 Web 应用程序交互,不妨考虑利用 JSON 来优化应用间的数据传递流程。

引用链接

[1] 

PostgreSQL 文档: https://www.postgresql.org/docs/9.3/functions-json.html

关注公众号,了解更多社区动态


推荐阅读 -

手把手教你在 openKylin 上部署 IvorySQL 4.4

在 PostgreSQL 中设置调试环境以更好地理解 OpenSSL API

深入理解 PostgreSQL Planner:简化扫描路径与查询计划

IvorySQL 增量备份与合并增量备份功能解析

DeepSeek 加持!IvorySQL 文档智能助手正式上线!

如何在 PostgreSQL 中运行 TLS 回归测试

版本发布| IvorySQL 4.4 发布

如何利用 PostgreSQL 的 JSONB API 作为扩展的轻量级 JSON 解析器

IvorySQL v4 逻辑复制槽同步功能解析:高可用场景下的数据连续性保障

表访问方法:PostgreSQL 中数据更新的处理方式

「2024 年度技术精华盘点」IvorySQL & PostgreSQL 技术干货全解析!

版本发布 | IvorySQL 4.2 发布

IvorySQL 4.0 之 Invisible Column 功能解析

从 PostgreSQL 升级至 IvorySQL 4.0

IvorySQL 4.0 之兼容 Oracle 包功能设计思路解读

IvorySQL 升级指南:从 3.x 到 4.0 的平滑过渡

IvorySQL 4.0 发布:全面支持 PostgreSQL 17

- 关于 IvorySQL -
IvorySQL 是由瀚高股份主导研发的一款开源的兼容 Oracle 的 PostgreSQL。IvorySQL 与 PostgreSQL 国际社区紧密合作,保持与最新 PG 版本内核同步,为用户提供便捷的升级体验。基于双 Parser 架构设计,100% 与原生 PostgreSQL 兼容,支持丰富的 PostgreSQL 周边工具和扩展,并根据用户需求提供定制化工具。同时,IvorySQL 提供更全面灵活的 Oracle 兼容功能,具备高度的 SQL 和 PL/SQL 兼容性能够为企业构建更加高效、稳定和灵活的数据库解决方案。
官网:https://www.ivorysql.org
GitHub(欢迎点击 star 收藏哦):https://github.com/IvorySQL/IvorySQL
社群:微信搜索“ivorysql_official” 添加小助理进群



文章转载自IvorySQL开源数据库社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论