JSON 系列之1:将 JSON 数据存储在 Oracle 数据库中

news/2024/12/28 12:30:04/

本文为Oracle数据库JSON学习系列的第一篇,讲述如何将JSON文档存储到数据库中,包括了版本为19c和23ai的情形。

19c中的JSON

先来看一下数据库版本为19c时的情形。

创建表colortab,其中color列的长度设为4000。若color的长度需要设为32767,则init.ora 参数 MAX_STRING_SIZE 必须设置为 EXTENDED。

DROP TABLE colortab PURGE;CREATE TABLE colortab (id    NUMBER,color VARCHAR2(4000)
);

插入4条数据:

INSERT INTO colortab VALUES ( 1,'{"color": "black","rgb": [0,0,0],"hex": "#000000"}
' );INSERT INTO colortab VALUES ( 2,'{"color": "orange red","rgb": [255,69,0],"hex": "#FF4500"}
' );INSERT INTO colortab VALUES ( 3,'{color: "gold","rgb": [255,215,0],"hex": "#FFD700 "}
' );INSERT INTO colortab VALUES ( 4,'I am not valid JSON' );COMMIT;

查看这些记录,会发现记录3的color字段并没有用双引号括起,于严格的JSON定义不符,但松散的JSON定义是允许的:
在这里插入图片描述
这可以通过如下来证明:

SQL> set echo on
SQL> SELECT id FROM colorTab WHERE color IS NOT JSON;ID
----------4SQL> 
SQL> SELECT id FROM colorTab WHERE color IS NOT JSON STRICT;ID
----------34

在Oracle 23ai JSON Developer’s Guide中,松散的语法称为Lax JSON Syntax,是默认的。严格的则称为Strict JSON Syntax。

插入一条新纪录,此记录符合Strict JSON Syntax,但具有重复的key:“color”。

INSERT INTO colortab VALUES ( 5,'{"color": "black","rgb": [0,0,0],"hex": "#000000","color": "white"}
' );COMMIT;

子句可以排除具有重复key的JSON。不过检查重复键是有代价的,所以一般是不做的:

SQL> SELECT id FROM colorTab WHERE color IS JSON STRICT;ID
----------125SQL> SELECT id FROM colorTab WHERE color IS JSON STRICT WITH UNIQUE KEYS;ID
----------12

如果只想让列存合法的JSON,在19c版本可以通过IS JSON约束。

TRUNCATE TABLE colorTab;ALTER TABLE colorTab ADD CONSTRAINT ensure_json CHECK (color IS JSON);

此时,插入记录4时报错:

错误报告 -
ORA-02290: 违反检查约束条件 (SSB.ENSURE_JSON)https://docs.oracle.com/error-help/db/ora-02290/

如果约束是CHECK (color IS JSON STRICT),则插入记录4时报错同上。

JSON的信息可以从字典视图中查看:

col table_name for a10
col column_name for a16
SELECT * FROM USER_JSON_COLUMNS WHERE table_name = 'COLORTAB';TABLE_NAME OBJEC COLUMN_NAME      FORMAT    DATA_TYPE    
---------- ----- ---------------- --------- -------------
COLORTAB   TABLE COLOR            TEXT      VARCHAR2   

最后再说一点,上例中的JSON是用VARCHAR2来存的,此外还可以用CLOB和BLOB。通常会建议BLOB,因为BLOB占用空间更小,从而引发的I/O更少。

Internally, CLOB encodes characters as UCS2 (similar to UTF16) which means every character takes up two bytes. BLOB does not perform such re-encoding but instead stores the Unicode (UTF8) bytes unmodified - thus requiring half the storage size for ASCII characters, and half the IO to load it.

23ai中的JSON

23ai支持原生JSON,因此表的定义变为:

drop table colortab purge;
CREATE TABLE colortab (id    NUMBER,color JSON
);

JSON 数据类型的实例使用 OSON 格式存储。OSON 是 Oracle 针对 Oracle 数据库服务器和 Oracle 数据库客户端中的查询和更新而优化的二进制 JSON 格式。

根据Oracle Database JSON Capabilities Specification,单个JSON实例的存储限制为32MB。

此时插入之前的5条数据。

插入记录4时,报错如下:

错误报告 -
ORA-40441: JSON 语法错误
JZN-00078: Invalid JSON keyword 'I' (line 1, position 1)https://docs.oracle.com/error-help/db/ora-40441/More Details :
https://docs.oracle.com/error-help/db/ora-40441/
https://docs.oracle.com/error-help/db/jzn-00078/

插入记录5时,报错如下:

错误报告 -
SQL 错误: ORA-40473: JSON 对象中存在重复的键名 'color'
JZN-00007: Object member key 'color' is not uniquehttps://docs.oracle.com/error-help/db/ora-40473/40473. 00000 -  "duplicate key names '%s' in JSON object"
*Cause:    The provided JavaScript Object Notation (JSON) data had duplicatekey names in one object.
*Action:   Provide JSON data with unique key names in each JSON object.More Details :
https://docs.oracle.com/error-help/db/ora-40473/
https://docs.oracle.com/error-help/db/jzn-00007/

这说明23ai JSON默认语法是Lax JSON Syntax,并且不允许重复键。文档 也是这么说的:

JSON 标准建议 JSON 对象不要有重复的字段名称。Oracle 数据库通过引发错误来强制 JSON 类型数据遵循此要求。

查看字典视图,数据类型为JSON,存储格式为OSON:

SQL> col table_name for a10
SQL> col column_name for a16
SQL> SELECT * FROM USER_JSON_COLUMNS WHERE table_name = 'COLORTAB';TABLE_NAME OBJEC COLUMN_NAME      FORMAT    DATA_TYPE    
---------- ----- ---------------- --------- -------------
COLORTAB   TABLE COLOR            OSON      JSON         

Oracle称所有非OSON存储的JSON为文本JSON(Textual JSON)。

JSON数据类型无法指定Strict JSON Syntax,按照文档5.3 Specifying Strict or Lax JSON Syntax 的说法:

Oracle 数据库的默认 JSON 语法是宽松的。严格或宽松语法仅对 SQL/JSON 条件 is json 和 is not json 有意义。所有其他 SQL/JSON 函数和条件都使用宽松语法来解释输入,并在返回输出时使用严格语法。

如果您需要确保特定文本 JSON 数据具有严格正确的语法,请先使用 is json 或 is not json 进行检查。

参考

  • Storing JSON data in the Oracle database
  • JSON Developer’s Guide

http://www.ppmy.cn/news/1558054.html

相关文章

HDFS与HBase有什么关系?

1 、 HDFS 文件存储系统和 HBase 分布式数据库 HDFS 是 Hadoop 分布式文件系统。 HBase 的数据通常存储在 HDFS 上。 HDFS 为 HBase 提供了高可靠性的底层存储支持。 Hbase 是 Hadoop database ,即 Hadoop 数据库。它是一个适合于非结构化数据存储的数据库, HBase 基于列的…

golang 熔断限流降级

限流 - 2k 但是我的服务能力只有1k,所以这个时候多出来的流量怎么办: 1. 拒绝 2. 排队等待。用户体验不太好: 当前访问用户过多,请稍后重试和你的服务直接挂了 用户体验降级了 - 原本是访问流畅,下单流畅 -> 当前访…

基于微信小程序的在线教育平台设计与实现

标题:基于微信小程序的在线教育平台设计与实现 内容:1.摘要 本文介绍了基于微信小程序的在线教育平台的设计与实现。首先,阐述了在线教育的背景和发展趋势,指出了微信小程序在教育领域的应用前景。其次,详细描述了平台的设计思路和实现方法&…

专业的内外网数据交换方案 可解决安全、效率、便捷3大问题

内外网数据交换是很多企业和行业都会面临的场景,既然隔离了内外网,重中之重就是要确保数据的安全性,其次在数据流转交换过程中,不能太繁琐复杂,需要让用户快速、便捷的进行数据交换。首先我们来看看,在进行…

蓝桥杯物联网开发板硬件组成

第一节 开发板简介 物联网设计与开发竞赛实训平台由蓝桥杯大赛技术支持单位北京四梯科技有限公司设计和生产,该产品可用于参加蓝桥杯物联网设计与开发赛道的竞赛实训或院校相关课程的 实践教学环节。 开发板基于STM32WLE5无线微控制器设计,芯片提供了25…

【AI绘画】无限制生成任意IP角色,完全免费!最新文生图-Ideogram AI,比Flux还牛!

家人们!今天分享我近期玩得最多的一款AI,出图效果特强,主要不受任何限制!玩起来极为有趣的最新AI文生图工具——Ideogram AI 2.0 不仅做出来的作品人像效果逼真,而且连生成文字图都接近完美,操作傻瓜式&am…

大语言模型中的Agent;常见的Agent开发工具或框架

大语言模型中的Agent 大语言模型中的Agent是指以大语言模型为核心驱动,具有自主理解、感知、规划、记忆和使用工具等能力,能够自动化执行复杂任务的系统.以下是一些例子: AutoGPT:它相当于一个完整的工具包,可以为各种项目构建和运行自定义AI Agent。使用OpenAI的GPT-4和…

六、模型显示位置与放缩

参考文档 # https://docs.live2d.com/zh-CHS/cubism-sdk-manual/layout/ 查看 LAppLive2DManager.cpp 中的 ChangeScene 方法, void LAppLive2DManager::ChangeScene(Csm::csmInt32 index) {_sceneIndex index;if (DebugLogEnable){LAppPal::PrintLog("[AP…