使用 Oracle 數(shù)據(jù)庫進(jìn)行基于 JSON 的應(yīng)用程序開發(fā)
本文為“JSON-based Application Development with Oracle Database (and MongoDB compatibility)”翻譯+閱讀筆記。
副標(biāo)題為:版本 19c 和 21c,本地和云,自治JSON 數(shù)據(jù)庫以及適用于 MongoDB 的 Oracle 數(shù)據(jù)庫 API,版本為2022年2月,1.1版。
目的
本文檔概述了 Oracle Database 19c 和 21c 版本中包含的功能和增強(qiáng)功能以??及相關(guān)的 Oracle 技術(shù)。旨在幫助您理解為什么現(xiàn)代應(yīng)用程序開發(fā)經(jīng)常使用 JSON 作為數(shù)據(jù)持久化格式,以及為什么 Oracle Database 中的 JSON 功能非常適合滿足當(dāng)今開發(fā)人員尋求文檔存儲(chǔ)來持久化、查詢和處理應(yīng)用程序數(shù)據(jù)的需求。
模式靈活的應(yīng)用程序開發(fā)
現(xiàn)代應(yīng)用程序開發(fā)在不斷變化的環(huán)境中進(jìn)行。用戶期望應(yīng)用程序能夠適應(yīng)快速變化的業(yè)務(wù)需求,并能夠即時(shí)交付更新。所有這些都意味著開發(fā)人員需要一種靈活的數(shù)據(jù)持久性機(jī)制,以便在應(yīng)用程序發(fā)展過程中最大程度地減少停機(jī)時(shí)間或DBA的參與。關(guān)系模型缺乏這種靈活性:表具有靜態(tài)的“形狀”,應(yīng)用程序更改需要修改它們(例如添加新列),這通常需要數(shù)據(jù)庫管理員(DBA)來完成。此外,現(xiàn)有數(shù)據(jù)可能需要修改以適應(yīng)新的模式。更重要的是:關(guān)系方法需要預(yù)先進(jìn)行模式設(shè)計(jì):應(yīng)用程序的對(duì)象(例如“客戶訂單”)被規(guī)范化到存儲(chǔ)對(duì)象值的表和列。一個(gè)應(yīng)用程序?qū)ο笸ǔ?huì)被規(guī)范化到多個(gè)表。這意味著簡單的put或get操作現(xiàn)在需要對(duì)所有參與表進(jìn)行插入和查詢,并滿足正確的連接條件。開發(fā)人員必須理解這種映射并使用 SQL 來表達(dá)它。
這里說的lacks flexibility 和upfront schema design都是事實(shí),但并不表示不好。JSON 文檔存儲(chǔ)提供了另一種可能性,何時(shí)用關(guān)系模型,何時(shí)用文檔存儲(chǔ),要看具體情況。
這種方法雖然已被證明可以持續(xù)數(shù)十年,但對(duì)于現(xiàn)代應(yīng)用程序開發(fā)來說通常被認(rèn)為過于僵化、正式和緩慢。此外,由于應(yīng)用程序和數(shù)據(jù)庫的變化通常必須同步,因此停機(jī)的可能性更高,運(yùn)營成本也更高。
文檔存儲(chǔ)(也稱為文檔數(shù)據(jù)庫)的工作方式不同,它不需要預(yù)先定義架構(gòu)(schema last)。相反,應(yīng)用程序數(shù)據(jù)以文檔形式建模,通常采用 JSON 格式。每個(gè)文檔都是自描述的(由命名的鍵/值對(duì)組成),因此無需外部架構(gòu)來理解這些值。此外,不同的文檔可以具有不同的鍵/值對(duì),這使得應(yīng)用程序可以輕松地通過動(dòng)態(tài)添加新的鍵/值對(duì)來演進(jìn),而無需修改現(xiàn)有的數(shù)據(jù)/文檔。因此,使用文檔進(jìn)行數(shù)據(jù)持久化可以提供開發(fā)人員所要求的靈活存儲(chǔ)機(jī)制。
由于基于 JSON 的 API 無處不在,處理 JSON 的另一個(gè)要求也隨之而來:REST 服務(wù)使用 JSON 作為輸入和輸出。如果第三方 API 發(fā)生更改,不再與該表匹配,將這些 JSON 值映射到表可能會(huì)導(dǎo)致應(yīng)用程序崩潰。相反,JSON 數(shù)據(jù)最好“原樣”(as is,即不經(jīng)改變的)存儲(chǔ)在支持 JSON 數(shù)據(jù)查詢的數(shù)據(jù)庫中。
NoSQL 文檔存儲(chǔ)的局限性
開發(fā)人員通常傾向于使用 NoSQL 產(chǎn)品,因?yàn)樗鼈儽徽J(rèn)為比關(guān)系數(shù)據(jù)庫更易于使用。典型的 NoSQL 文檔存儲(chǔ)將 JSON 文檔組織在集合中。由于數(shù)據(jù)模型簡單,僅由集合和文檔組成,這些系統(tǒng)提供的功能也比較簡單,在報(bào)告或分析用例方面尤其有限(Join和Aggregation都不是Document Store擅長的)。
如果出現(xiàn)此類需求,開發(fā)人員通常會(huì)部署第二個(gè)(關(guān)系型)數(shù)據(jù)庫并存儲(chǔ)兩次數(shù)據(jù);這通常需要一個(gè) ETL 流程(提取、轉(zhuǎn)換、加載)將數(shù)據(jù)轉(zhuǎn)換為關(guān)系格式。
此外,NoSQL 文檔存儲(chǔ)通常不支持復(fù)雜的事務(wù)和引用完整性約束,因此數(shù)據(jù)一致性現(xiàn)在成了開發(fā)人員需要解決的問題。所需的“變通方法”會(huì)增加系統(tǒng)復(fù)雜性,降低安全性,導(dǎo)致不一致,并產(chǎn)生新的問題,例如跨不同數(shù)據(jù)庫的時(shí)間點(diǎn)恢復(fù)。
由于這種額外的復(fù)雜性,總體擁有成本往往很高,并且不再能兌現(xiàn)簡易 NoSQL 產(chǎn)品的承諾。
使用 Oracle 數(shù)據(jù)庫作為文檔存儲(chǔ)
Oracle 數(shù)據(jù)庫提供與專用 NoSQL 文檔存儲(chǔ)相同的應(yīng)用程序開發(fā)體驗(yàn):它可以存儲(chǔ)、管理和索引 JSON 文檔,并提供與常見 NoSQL 產(chǎn)品類似的 NoSQL 文檔存儲(chǔ) API。它甚至支持與 MongoDB(最流行的文檔存儲(chǔ)之一)兼容的 API。
此外(與 NoSQL 產(chǎn)品不同),Oracle 數(shù)據(jù)庫提供針對(duì) JSON 文檔的復(fù)雜 SQL 查詢、報(bào)表、分析和機(jī)器學(xué)習(xí)功能。這使您可以集成 JSON 和關(guān)系數(shù)據(jù),并將它們連接到同一個(gè)查詢中。
由于 JSON 特性已集成到 Oracle 數(shù)據(jù)庫中,因此其所有企業(yè)級(jí)特性(例如可用性、安全性、可擴(kuò)展性、性能和可管理性)均完全支持 JSON 數(shù)據(jù)。
在 Oracle 數(shù)據(jù)庫中存儲(chǔ)和管理 JSON 文檔
Oracle 數(shù)據(jù)庫 21c 版新增了 SQL 數(shù)據(jù)類型“JSON”,該數(shù)據(jù)類型采用針對(duì)快速查詢和分段更新進(jìn)行了優(yōu)化的二進(jìn)制格式。
早期版本(例如 19c)允許使用 VARCHAR2、CLOB 或 BLOB 列存儲(chǔ) JSON 文檔。“IS JSON”SQL 檢查約束可確保該列僅包含有效的 JSON 文檔,從而使數(shù)據(jù)庫能夠識(shí)別該列正在用作 JSON 文檔的容器。Oracle 的 JSON 功能專注于為模式靈活的開發(fā)和基于文檔的存儲(chǔ)提供全面支持。
因此,盡管 Oracle 數(shù)據(jù)庫知道給定列包含 JSON 文檔,但數(shù)據(jù)庫在存儲(chǔ)、索引和查詢這些文檔時(shí),并不知道其內(nèi)部結(jié)構(gòu)(鍵/值對(duì))。開發(fā)人員可以根據(jù)需要自由更改 JSON 文檔的結(jié)構(gòu)。
Oracle 數(shù)據(jù)庫為其所有高級(jí)功能(包括災(zāi)難恢復(fù)、復(fù)制、壓縮和加密)提供全面的 JSON 支持。此外,支持 Oracle 數(shù)據(jù)庫的產(chǎn)品(例如 Oracle GoldenGate 和 Oracle Data Integrator,以及第三方工具)也無縫支持存儲(chǔ)在數(shù)據(jù)庫中的 JSON 文檔。
自治 JSON 數(shù)據(jù)庫
Oracle 數(shù)據(jù)庫自 12.1.0.2 版本起就支持 JSON,并新增了許多 JSON 特性。
名為“自治 JSON 數(shù)據(jù)庫”(AJD) 的托管數(shù)據(jù)庫云服務(wù)提供了本技術(shù)報(bào)告中概述的功能,且價(jià)格遠(yuǎn)低于自治數(shù)據(jù)庫系列的其他成員。
除了支持文檔存儲(chǔ) API 之外,AJD 還完全能夠運(yùn)行任意 SQL 語句并將非 JSON 數(shù)據(jù)存儲(chǔ)在關(guān)系表中。
由于 AJD 面向 JSON 開發(fā)人員,因此非 JSON 數(shù)據(jù)的大小限制為 20GB;如果需要更多數(shù)據(jù),只需單擊鼠標(biāo)即可升級(jí)到自治事務(wù)處理 (ATP) 服務(wù)。
因此,AJD 并非一個(gè)需要不同技能或 API 的獨(dú)立開發(fā)環(huán)境。
作為自治數(shù)據(jù)庫平臺(tái)的一部分,AJD 用戶可充分受益于自治數(shù)據(jù)庫的自主驅(qū)動(dòng)、自主安全和自主修復(fù)功能。數(shù)據(jù)庫正常運(yùn)行時(shí)間最大化,自動(dòng)擴(kuò)展(最高可達(dá)配置 CPU 限制的三倍)功能以最低成本提供最高性能。
更多關(guān)于自治 JSON 數(shù)據(jù)庫服務(wù)的信息,請(qǐng)?jiān)L問:
https://www.oracle.com/autonomous-database/autonomous-json-database/
適用于 MongoDB 的 Oracle 數(shù)據(jù)庫 API(用于自治數(shù)據(jù)庫)
所有 Oracle 自治數(shù)據(jù)庫(包括自治 JSON 數(shù)據(jù)庫)均兼容 MongoDB:為 MongoDB 編寫的工具、驅(qū)動(dòng)程序和應(yīng)用程序可以使用 MongoDB 原生 API 連接到 Oracle 自治數(shù)據(jù)庫,該 API 將 MongoDB 數(shù)據(jù)庫操作透明地轉(zhuǎn)換為等效的 SQL/JSON 操作,然后在 Oracle 數(shù)據(jù)庫上執(zhí)行。
MongoDB 應(yīng)用程序通過 MongoDB API 進(jìn)行通信,就像它們?nèi)匀贿B接到 MongoDB 服務(wù)器一樣。
開發(fā)人員可以繼續(xù)使用他們的 MongoDB 技能和工具,同時(shí)還可以對(duì) MongoDB 集合中的 JSON 數(shù)據(jù)運(yùn)行 SQL 語句。這使得基于 JSON 數(shù)據(jù)進(jìn)行實(shí)時(shí) SQL 分析和機(jī)器學(xué)習(xí)成為可能。
還可以從關(guān)系數(shù)據(jù)生成 JSON,并將結(jié)果公開為與 MongoDB 兼容的集合,以便 MongoDB 應(yīng)用程序可以輕松訪問查詢結(jié)果或關(guān)系數(shù)據(jù)。
Oracle Database API for MongoDB 還支持 Compass、mongosh (mongo shell) 和 mongoimport/mongorestore 等 MongoDB 工具,從而簡化了遷移到 Oracle 的過程。
截至目前(2022 年 2 月),Oracle Database API for MongoDB 最初僅在共享自治數(shù)據(jù)庫 (ADDB) 上可用。詳情請(qǐng)?jiān)L問:
http://docs.oracle.com/en/database/oracle/mongodb-api/mgapi
簡單的 Oracle 文檔訪問 API (SODA)
由于 MongoDB 的 Oracle 數(shù)據(jù)庫 API 目前僅限于共享自治數(shù)據(jù)庫,Oracle 提供了另一個(gè)通用的文檔存儲(chǔ) API——云端(所有 Oracle 云數(shù)據(jù)庫)和本地均可使用:簡單 Oracle 文檔訪問 (SODA) API。
此 API 的設(shè)計(jì)初衷是支持模式靈活的應(yīng)用程序開發(fā),與 MongoDB 等常見的 NoSQL 文檔存儲(chǔ) API 非常相似。
使用 SODA,開發(fā)者無需學(xué)習(xí) SQL 即可處理 JSON 文檔和集合。相反,可以通過簡單的 API 直接調(diào)用針對(duì)集合和文檔的數(shù)據(jù)庫操作——該 API 不僅支持 REST,還支持 Java、Python、JavaScript (Node.js)、C 和 PL/SQL 等常用編程語言。
SODA for REST 是 Oracle REST 數(shù)據(jù)服務(wù) (ORDS) 的一部分,可以通過任何支持 REST/HTTP 調(diào)用的語言調(diào)用。Java、Python、Node.js 和 C 驅(qū)動(dòng)程序均為開源。
SODA 的概念模型與 MongoDB 非常相似:應(yīng)用程序?qū)ο笠?JSON 文檔的形式存儲(chǔ)在集合中。文檔用鍵標(biāo)識(shí)。集合用名稱標(biāo)識(shí)。異構(gòu)集合允許存儲(chǔ)非 JSON 對(duì)象,例如圖像。多個(gè)集合駐留在客戶端程序連接的數(shù)據(jù)庫中。
可以使用 SODA 命令訪問文檔,通常用于簡單的 CRUD 操作(創(chuàng)建、讀取 + 查找、更新、刪除),也可以使用 SQL:可以輕松地對(duì)同一 JSON 數(shù)據(jù)進(jìn)行報(bào)告、分析或機(jī)器學(xué)習(xí)。
我們通過 REST 和 Java 的示例來說明 SODA API。SODA 文檔以及驅(qū)動(dòng)程序和教程的鏈接可在此處找到:
https://www.oracle.com/database/technologies/appdev/json.html
SODA示例
以下 Java 代碼創(chuàng)建一個(gè)集合“orders”,并插入一個(gè) JSON 文檔。然后,它檢索 SODA 分配給該文檔的唯一鍵 (id)。SODA 也可以接受用戶生成的鍵。
OracleRDBMSClient client = new OracleRDBMSClient();
OracleDatabase db = client.getDatabase(conn);
OracleCollection orders = db.admin().createCollection("orders");
OracleDocument doc = orders.insertAndGet(db.createDocument('{…}'));
String id = doc.getKey();可以看到,數(shù)據(jù)庫、集合和文檔映射到 Java 類,這些類具有公開其功能的函數(shù)。
在 SODA for REST 中,HTTP 動(dòng)詞(例如 PUT、POST、GET 和 DELETE)映射到文檔上的 SODA 操作。URL 包含文檔的鍵或集合的名稱,以及數(shù)據(jù)庫主機(jī)名和授權(quán)憑據(jù)。SODA for REST 是一種 Oracle REST 數(shù)據(jù)服務(wù),依賴 ORDS 進(jìn)行身份驗(yàn)證和授權(quán)。由于篇幅原因,本示例省略了此部分。創(chuàng)建集合和插入文檔這兩個(gè)操作分別需要一次 REST 調(diào)用。第二次調(diào)用返回一個(gè)帶有指定鍵 (id) 的 HTTP 響應(yīng):
curl -X PUT http://<authUrlToOrds>/soda/latest/orders
curl -X POST -H "Content-type: application/json"
--upload-file document.json http://<urlToORDS>/soda/latest/orders
{ "items": [
{ "id": "A450557094D04957B36346F630CDDF9A",
"etag":"C13578001CBBC84022DCF5F7209DBF0E6DFFCC626E3B0400C3",
"lastModified": "2021-02-09T01:03:48.291462",
"created": "2021-02-09T01:03:48.291462"
}
],
"hasMore": false, "count": 1
}上述示例展示了文檔存儲(chǔ)與傳統(tǒng) SQL 數(shù)據(jù)庫的區(qū)別:新文檔以 JSON 對(duì)象的形式添加到集合中。數(shù)據(jù)庫對(duì)這些文檔中包含的鍵沒有任何限制。對(duì)于習(xí)慣于面向?qū)ο缶幊汰h(huán)境的開發(fā)人員來說,API 調(diào)用也更簡單。注意:SODA for REST 與其他語言驅(qū)動(dòng)程序(例如 Java)的區(qū)別在于,REST 是無狀態(tài)的,因此所有 REST 操作都會(huì)立即提交,而語言驅(qū)動(dòng)程序依賴于支持事務(wù)的數(shù)據(jù)庫連接(多個(gè)操作可以設(shè)置為原子操作)。
現(xiàn)在,讓我們使用 SODA 來檢索文檔。SODA 顯然支持通過鍵獲取文檔,但一種更有趣的數(shù)據(jù)查詢方式是查找所有滿足搜索條件(以 JSON 文檔形式表示)的文檔,我們稱之為 QueryByExample (QBE)。這是一個(gè)非?;镜?QBE,它會(huì)選擇所有字段“region”的值為“north”,且第二個(gè)字段“quantity”的值為 10 或更大的文檔:
{"region":"north", "quantity":{"$gte":10}}(可以使用 skip 和 limit 對(duì)大量結(jié)果進(jìn)行分頁。)
以下 Java 代碼片段執(zhí)行 QBE 搜索,將結(jié)果限制為前 100 個(gè)文檔并打印所有文檔鍵。變量“qbe”的值為上述的QBE。
OracleCollection coll = database.openCollection("orders");
OracleCursor results = coll.find().filter(qbe).limit(100).getCursor();
while (results.hasNext()) {
OracleDocument doc = results.next();
System.out.println(doc.getKey());
}REST 參數(shù) action=query 表示 POST 包含 QBE 請(qǐng)求。
curl -X POST -H "Content-type: application/json" --data
'{"region":"north", "quantity":{"$gte":10}}'
http://<urlToORDS>/ords/SCOTT/soda/latest/orders?action=query對(duì)存儲(chǔ)在 Oracle 數(shù)據(jù)庫中的 JSON 內(nèi)容進(jìn)行分析和報(bào)告
如上所述,Oracle 數(shù)據(jù)庫為應(yīng)用程序開發(fā)提供了 NoSQL 文檔存儲(chǔ)的諸多優(yōu)勢。使用 Oracle 數(shù)據(jù)庫的一大優(yōu)勢在于,它還能將 SQL 的全部功能應(yīng)用于相同的 JSON 文檔。這得益于 JSON 集合由自動(dòng)創(chuàng)建的常規(guī)表支持。它們包含一個(gè)用于存儲(chǔ)文檔的 JSON 列,以及用于唯一鍵 (ID) 和元數(shù)據(jù)(例如創(chuàng)建日期)的附加列。訂單集合由以下表支持:
SQL> describe "orders" Name Null? Type ---------------------------------------- ID NOT NULL VARCHAR2(255) CREATED_ON NOT NULL TIMESTAMP(6) LAST_MODIFIED NOT NULL TIMESTAMP(6) VERSION NOT NULL VARCHAR2(255) JSON_DOCUMENT JSON
Oracle 數(shù)據(jù)庫支持多種 SQL 操作符來處理 JSON:
| 操作 | 描述 |
|---|---|
| IS JSON | 測試表達(dá)式是否包含 JSON |
| JSON_Value | 提取標(biāo)量 SQL 值 |
| JSON_Query | 提取 JSON 片段 |
| JSON_Exists | 測試是否滿足一個(gè)或多個(gè)條件 |
| JSON_TextContains | 對(duì) JSON 字段進(jìn)行全文搜索 |
| JSON_Table | 將 JSON 投影到關(guān)系模型 |
| JSON_Object[Agg] | 生成 JSON 對(duì)象 |
| JSON_Array[Agg] | 生成 JSON 數(shù)組 |
| JSON_Transform | 修改 JSON,例如作為更新的一部分 |
| JSON_Mergepatch | 合并兩個(gè) JSON 對(duì)象 |
| JSON_Dataguide | 用于構(gòu)建模式的 JSON 示例 |
許多運(yùn)算符依賴于路徑表達(dá)式來在 JSON 數(shù)據(jù)中進(jìn)行導(dǎo)航,并可選地使用路徑謂詞過濾。運(yùn)算符和路徑表達(dá)式的詳細(xì)描述可以在 JSON 開發(fā)者指南中找到:
https://docs.oracle.com/en/database/oracle/oracle-database/21/adjsn/
對(duì)于以下示例,我們假設(shè)此集合/表包含采購訂單文件:
{
"PONumber": 1600,
"Reference": "ABULL-20140421",
"Requestor": "Alexis Bull",
"User": "ABULL",
"CostCenter": "A50",
"Instructions": {
"name": "Alexis Bull",
"Address": {
"street": "200 Sporting Green",
"city": "South San Francisco",
"state": "CA",
"zipCode": 99236,
"country": "United States of America"
},
"Phone": [
{
"type": "Office",
"number": "823-555-9969"
}
]
},
"Special Instructions": "Counter to Counter",
"LineItems": [...]
}使用 SQL 查詢 JSON 數(shù)據(jù)的最簡單方法是簡單的點(diǎn)符號(hào),它允許導(dǎo)航 JSON 結(jié)構(gòu)并選擇值。
SQL> select j.PO_DOCUMENT.Reference,
j.PO_DOCUMENT.Requestor,
j.PO_DOCUMENT.CostCenter,
j.PO_DOCUMENT.Instructions.Address.city
from J_PURCHASEORDER j
where j.PO_DOCUMENT.PONumber = 1600;
REFERENCE REQUESTOR COSTCENTER SHIPPINGINSTRUCTIONS
-------------------- -------------- ------------ ---------------------
ABULL-20140421 Alexis Bull A50 South San FranciscoJSON_TABLE 是一個(gè)常用于將 JSON 數(shù)據(jù)映射到關(guān)系模型的表函數(shù),以便訪問它。這有很多好處:
- 關(guān)系模型非常適合分析型查詢,尤其是維度和事實(shí)存儲(chǔ)在不同集合中的數(shù)倉查詢。使用物化視圖甚至可以“預(yù)先計(jì)算”這些連接。
- 操作關(guān)系模型的工具可以用來處理 JSON,例如報(bào)表生成器、儀表板和機(jī)器學(xué)習(xí),它們可以直接應(yīng)用于 JSON 數(shù)據(jù)。
- 數(shù)據(jù)分析師可以運(yùn)用 SQL 語言和調(diào)優(yōu)技能,無需手動(dòng)將 JSON 數(shù)據(jù)映射到表或編寫自定義代碼。
JSON_TABLE 使用一組 JSON 路徑表達(dá)式將 JSON 文檔中的內(nèi)容投影為虛擬表中的關(guān)系列。您可以在 SQL 查詢的 FROM 子句中使用 JSON_TABLE 表達(dá)式,就像使用關(guān)系表一樣。以下示例從 JSON 文檔集合中投影一組列。每個(gè) JSON 路徑表達(dá)式從文檔返回一個(gè)標(biāo)量值,因此為每個(gè)文檔生成虛擬表中的一行。
SQL> select jt.*
from J_PURCHASEORDER p,
JSON_TABLE(p.PO_DOCUMENT, '$' columns
PO_NUMBER NUMBER(10) path '$.PONumber',
REFERENCE VARCHAR2(30 CHAR) path '$.Reference',
REQUESTOR VARCHAR2(32 CHAR) path '$.Requestor',
USERID VARCHAR2(10 CHAR) path '$.User',
COSTCENTER VARCHAR2(16 CHAR) path '$.CostCenter',
TELEPHONE VARCHAR2(16 CHAR) path '$.Instructions.Phone[0].number'
) jt
where PO_NUMBER > 1599 and PO_NUMBER < 1602;
PO_NUMBER REFERENCE REQUESTOR USERID COSTCENTER TELEPHONE
----------- --------------- ------------- ------- ----------- --------------
1600 ABULL-20140421 Alexis Bull ABULL A50 909-555-7307
1601 ABULL-20140423 Alexis Bull ABULL A50 909-555-9119
2 rows selected.JSON_TABLE 還支持帶有嵌套數(shù)組的 JSON 文檔:NESTED PATH 迭代嵌套的“LineItems”數(shù)組:嵌套數(shù)組外的值被重復(fù)(PO_NUMBER),因?yàn)樗鼈冞m用于整個(gè)嵌套數(shù)組。
SQL> select jt.*
from J_PURCHASEORDER p,
JSON_TABLE(p.PO_DOCUMENT, '$' columns(
PO_NUMBER NUMBER(10) path '$.PONumber',
REFERENCE VARCHAR2(30 CHAR) path '$.Reference',
NESTED PATH '$.LineItems[*]' columns(
ITEMNO NUMBER(16) path '$.ItemNumber',
DESCRIPTION VARCHAR2(32) path '$.Part.Description',
UPCCODE VARCHAR2(14) path '$.Part.UPCCode',
QUANTITY NUMBER(5,4) path '$.Quantity',
UNITPRICE NUMBER(5,2) path '$.Part.UnitPrice'
)
) jt
where PO_NUMBER > 1599 and PO_NUMBER < 1602;
PO_NUMBER REFERENCE ITEMNO DESCRIPTION UPCCODE QUANTITY UNITPRICE
----------- --------------- ------ -------------------------- -------- -------- ----------
1600 ABULL-20140421 1 One Magic Christmas 13131092 9 19.95
1600 ABULL-20140421 2 Lethal Weapon 8539162 5 19.95
1601 ABULL-20140423 1 Star Trek 34 9736600 1 19.95
1601 ABULL-20140423 2 New Blood 4339605 8 19.95
1601 ABULL-20140423 3 The Bat 1313111 3 19.95
1601 ABULL-20140423 4 Standard Deviants 6318650 7 27.95
1601 ABULL-20140423 5 Darkman 2 2519203 7 19.95
7 rows selected.使用 JSON_TABLE,可以將任意復(fù)雜的 JSON 結(jié)構(gòu)投影到關(guān)系模型中。JSON_TABLE 查詢可以作為視圖公開——對(duì)于該視圖的任何使用者來說,JSON 數(shù)據(jù)的訪問方式就像一個(gè)由行和列組成的常規(guī)表,其中包含標(biāo)量值。這也使得使用不支持 JSON 數(shù)據(jù)模型的關(guān)系工具成為可能。
JSON 數(shù)據(jù)指南
JSON_TABLE 的一個(gè)常見用途是創(chuàng)建關(guān)系視圖,允許不了解 JSON 的用戶和工具處理文檔。JSON_Dataguide 可以通過對(duì)集合中的所有 JSON 文檔進(jìn)行采樣并識(shí)別字段名稱和數(shù)據(jù)類型來自動(dòng)創(chuàng)建視圖。以下示例展示了如何自動(dòng)創(chuàng)建視圖“order_view”。視圖定義包含一個(gè)與上述類似的 JSON_Table 表達(dá)式。
DECLARE
dg CLOB; -- This variable stores the derived JSON schema
BEGIN
-- JSON_Dataguide samples all documents and builds a JSON schema
SELECT JSON_Dataguide(json_document, dbms_json.FORMAT_HIERARCHICAL)
INTO dg
FROM orders;
-- Using this JSON schema, a JSON_TABLE view can be automatically created
dbms_json.create_view('order_view', 'orders', 'json_document', dg);
ENDJSON 生成
Oracle 數(shù)據(jù)庫還可以從關(guān)系以及 JSON 數(shù)據(jù)生成新的 JSON 數(shù)據(jù)。例如,這可以生成 JSON 格式的報(bào)告。
以下示例展示了如何連接示例表“員工”和“部門”中的數(shù)據(jù),并將結(jié)果作為新的 JSON 文檔返回。
SELECT JSON_ObjectAgg(
d.name VALUE (
SELECT JSON_ArrayAgg(
JSON_Object(e.name)
)
FROM employees e
WHERE e.department_no = d.department_no
)
)
FROM departments d;
-----------------------------------------------
{
"ACCOUNTING": [
{"name": "CLARK"},
{"name": "KING"},
{"name": "MILLER"}
],
"RESEARCH": [
{"name": "SMITH"},
{"name": "JONES"},
...
]
}請(qǐng)注意,SQL/JSON 生成運(yùn)算符只是添加到常規(guī) SQL 查詢中,這再次展示了 JSON 和表在 O??racle 數(shù)據(jù)庫中的良好結(jié)合使用。還可以將生成的文檔插入到集合中,以便 SODA 或 MongoDB API 訪問。
結(jié)論:為什么使用 Oracle 數(shù)據(jù)庫作為文檔存儲(chǔ)?
本技術(shù)報(bào)告介紹了 Oracle 數(shù)據(jù)庫的特性,這些特性支持使用存儲(chǔ)在集合中的 JSON 文檔進(jìn)行模式靈活的開發(fā)。如今,許多 NoSQL 系統(tǒng)都支持這種開發(fā)范式。為什么組織應(yīng)該選擇 Oracle 數(shù)據(jù)庫而不是 NoSQL 系統(tǒng)呢?
Oracle數(shù)據(jù)庫專為企業(yè)級(jí)應(yīng)用而構(gòu)建。許多現(xiàn)代企業(yè)級(jí)關(guān)系型數(shù)據(jù)庫理所當(dāng)然的功能,典型的NoSQL文檔存儲(chǔ)卻無法提供:
- 復(fù)雜的索引、查詢優(yōu)化和并行執(zhí)行
- 完全符合ACID的事務(wù),且不受大小/時(shí)長限制。
- 高級(jí)安全功能,例如數(shù)據(jù)屏蔽和密鑰管理
- 數(shù)據(jù)管理功能,例如壓縮和數(shù)據(jù)歸檔
- 強(qiáng)大的備份功能,支持對(duì)象級(jí)時(shí)間點(diǎn)恢復(fù)
- 內(nèi)置過程式語言和服務(wù)器端函數(shù)
NoSQL 系統(tǒng)通常缺乏報(bào)告和分析操作的功能。隨著 JSON 文檔的數(shù)量和價(jià)值不斷增長,對(duì)跨文檔報(bào)告和分析功能的需求也日益增長。以前,開發(fā)人員必須從 NoSQL 導(dǎo)出數(shù)據(jù),并應(yīng)用復(fù)雜的 ETL(提取、轉(zhuǎn)換和加載)流程,才能將其用于支持靈活報(bào)告的數(shù)據(jù)存儲(chǔ)。雖然許多 NoSQL 系統(tǒng)現(xiàn)在都認(rèn)識(shí)到需要使用表結(jié)構(gòu)化格式來訪問數(shù)據(jù),有些系統(tǒng)甚至引入了類似 SQL 的基本語言,但 Oracle Database 憑借其先進(jìn)的 SQL 分析功能和可擴(kuò)展的并行 SQL 基礎(chǔ)架構(gòu),如今已將成熟的 ISO 標(biāo)準(zhǔn) SQL 的全部功能提供給 JSON 文檔存儲(chǔ)。
使用 NoSQL 文檔存儲(chǔ)的組織還必須面對(duì)數(shù)據(jù)可能被孤立(數(shù)據(jù)孤島)起來的問題:他們的關(guān)系數(shù)據(jù)由一個(gè)數(shù)據(jù)庫管理,而 JSON 文檔則由另一個(gè)數(shù)據(jù)庫管理。使用單獨(dú)的 JSON 文檔數(shù)據(jù)存儲(chǔ)意味著,當(dāng)需要將以 JSON 格式存儲(chǔ)的信息與組織管理的其他類型的數(shù)據(jù)(通常包括關(guān)系數(shù)據(jù))相結(jié)合時(shí),即使是最基本的任務(wù),也需要開發(fā)和維護(hù)特殊的應(yīng)用程序代碼(需要集成)。
Oracle 融合數(shù)據(jù)庫提供專為應(yīng)用程序開發(fā)人員設(shè)計(jì)的文檔存儲(chǔ)功能,同時(shí)允許這些應(yīng)用程序開發(fā)人員利用 Oracle 成熟數(shù)據(jù)庫平臺(tái)的所有其他優(yōu)勢。
到此這篇關(guān)于使用 Oracle 數(shù)據(jù)庫進(jìn)行基于 JSON 的應(yīng)用程序開發(fā)的文章就介紹到這了,更多相關(guān)Oracle 數(shù)據(jù)庫 JSON 應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
直接拷貝數(shù)據(jù)文件實(shí)現(xiàn)Oracle數(shù)據(jù)遷移
Oracle 數(shù)據(jù)遷移是比較麻煩的,對(duì)菜鳥來說更是如此。最近由于更換服務(wù)器,需要將Oracle遷移到另外一臺(tái)機(jī)器,在兩個(gè)服務(wù)器環(huán)境相同,以及 Oracle版本相同的前提下,通過直接拷貝數(shù)據(jù)文件到新服務(wù)器,就可以直接遷移成功。這里記錄一下遷移步驟。需要的朋友可以參考。2017-01-01
Oracle查詢結(jié)果只獲取一行數(shù)據(jù)的幾種方法
oracle是一種流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它提供了一種強(qiáng)大的查詢語言,讓用戶可以輕松地查詢一條記錄,這篇文章主要給大家介紹了關(guān)于Oracle查詢結(jié)果只獲取一行數(shù)據(jù)的幾種方法,需要的朋友可以參考下2024-05-05
Oracle導(dǎo)dmp出現(xiàn)文件ORA-12154: TNS: 無法解析指定的連接標(biāo)識(shí)符問題的解決方案
這篇文章主要介紹了Oracle導(dǎo)dmp出現(xiàn)文件ORA-12154: TNS: 無法解析指定的連接標(biāo)識(shí)符問題的解決方案,需要的朋友可以參考下2017-03-03
Oracle數(shù)據(jù)庫批量變更字段類型的實(shí)現(xiàn)步驟
我有個(gè)項(xiàng)目使用Oracle數(shù)據(jù)庫,運(yùn)行幾年后數(shù)據(jù)量較大,需要對(duì)數(shù)據(jù)庫做一次優(yōu)化,其中有些字段類型類型需要調(diào)整,這里分享一下實(shí)現(xiàn)步驟,感興趣的朋友可以參考下2024-02-02
Oracle Linux 6.8安裝 mysql 5.7.17的詳細(xì)教程
這篇文章主要介紹了Oracle Linux 6.8安裝 mysql 5.7.17的詳細(xì)教程,需要的朋友可以參考下2017-06-06
oracle連接數(shù)據(jù)庫報(bào)錯(cuò)ORA-12170:TNS連接超時(shí)解決辦法
這篇文章主要給大家介紹了關(guān)于oracle連接數(shù)據(jù)庫報(bào)錯(cuò)ORA-12170:TNS連接超時(shí)的解決辦法,ORA-12170是Oracle數(shù)據(jù)庫連接錯(cuò)誤,表示數(shù)據(jù)庫連接超時(shí),文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
Oracle數(shù)據(jù)庫統(tǒng)計(jì)信息方法詳解
這篇文章主要介紹了如何查看和收集Oracle數(shù)據(jù)庫中的統(tǒng)計(jì)信息,包括表、索引和列的統(tǒng)計(jì)信息,介紹了DBMS_STATS包的功能和使用方法,以及如何通過分析和刪除統(tǒng)計(jì)信息來優(yōu)化數(shù)據(jù)庫性能,需要的朋友可以參考下2024-12-12
判定一個(gè)字符串是否為有效時(shí)間的函數(shù)
判定時(shí)間是否有效的函數(shù),為有效時(shí)間則返回1,不是有效時(shí)間則返回0,需要的朋友可以參考下2014-07-07

