欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PostgreSQL中json數(shù)據(jù)類型詳解

 更新時(shí)間:2023年04月01日 09:50:41   作者:夜郎king  
json數(shù)據(jù)也可以被存儲(chǔ)為text,但是 與text數(shù)據(jù)類型相比,JSON 數(shù)據(jù)類型的優(yōu)勢(shì)在于能強(qiáng)制要求每個(gè)被存儲(chǔ)的值符合 JSON 規(guī)則,這篇文章主要介紹了PostgreSQL中json數(shù)據(jù)類型,需要的朋友可以參考下

前言

        JSON(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式。它基于 ECMAScript(European Computer Manufacturers Association, 歐洲計(jì)算機(jī)協(xié)會(huì)制定的js規(guī)范)的一個(gè)子集,采用完全獨(dú)立于編程語言的文本格式來存儲(chǔ)和表示數(shù)據(jù)。簡潔和清晰的層次結(jié)構(gòu)使得 JSON 成為理想的數(shù)據(jù)交換語言。 易于人閱讀和編寫,同時(shí)也易于機(jī)器解析和生成,并有效地提升網(wǎng)絡(luò)傳輸效率。其實(shí)JSON作為一種數(shù)據(jù)規(guī)范和標(biāo)準(zhǔn),在用于接口交換,系統(tǒng)配置,數(shù)據(jù)存儲(chǔ)方面擁有得天獨(dú)厚的一席之地。

       在存儲(chǔ)技術(shù)已經(jīng)高速發(fā)達(dá)的今天,對(duì)于json數(shù)據(jù)的存儲(chǔ)和使用,有多重方式。比如在緩存界的一哥Redis,文檔數(shù)據(jù)庫的佼佼者M(jìn)ongodb等等。上述兩者的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)也是JSON,基于json豐富的開發(fā)接口和支持。

      隨著技術(shù)和業(yè)務(wù)的發(fā)展,除了上述兩者之外,許多傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,如MySQL、PostgreSQL(以下簡稱PG)等等都開始支持json數(shù)據(jù)的存儲(chǔ)和高效查詢。在不增加額外的技術(shù)棧學(xué)習(xí)成本之下,基于統(tǒng)一的數(shù)據(jù)庫庫知識(shí)來滿足日常的業(yè)務(wù)需求,也是一種合理的技術(shù)選型(滿足了日常業(yè)務(wù)即可)。本文重點(diǎn)講述在PG中關(guān)于json類型的介紹,json和jsonb的區(qū)別,json和jsonb的基本操作、輸出區(qū)別、包含測(cè)試等內(nèi)容,讓各位對(duì)json類型有一個(gè)基本直觀的認(rèn)識(shí)。理解最基礎(chǔ)的數(shù)據(jù)庫操作。

一、PG數(shù)據(jù)庫中JSON的類型

       json數(shù)據(jù)也可以被存儲(chǔ)為text,但是 與text數(shù)據(jù)類型相比,JSON 數(shù)據(jù)類型的優(yōu)勢(shì)在于能強(qiáng)制要求每個(gè)被存儲(chǔ)的值符合 JSON 規(guī)則。也有很多 JSON 相關(guān)的函 數(shù)和操作符可以用于存儲(chǔ)在這些數(shù)據(jù)類型中的數(shù)據(jù)。基于text類型的數(shù)據(jù),無法直接利用數(shù)據(jù)庫的查詢技術(shù)來提高查詢效率。而且需要在應(yīng)用程序中進(jìn)行相關(guān)的轉(zhuǎn)換。眾所周知,PostgreSQL 提供存儲(chǔ)JSON數(shù)據(jù)的兩種類型:json 和 jsonb。

1、json和jsonb的區(qū)別

       json 和 jsonb數(shù)據(jù)類型接受幾乎完全相同的值集合作為輸入。 主要的實(shí)際區(qū)別之一是效率。json數(shù)據(jù)類型存儲(chǔ)輸入文本的精準(zhǔn)拷貝,處理函數(shù)必須在每 次執(zhí)行時(shí)必須重新解析該數(shù)據(jù)。而jsonb數(shù)據(jù)被存儲(chǔ)在一種分解好的 二進(jìn)制格式中,它在輸入時(shí)要稍慢一些,因?yàn)樾枰龈郊拥霓D(zhuǎn)換。但是 jsonb在處理時(shí)要快很多,因?yàn)椴恍枰馕?。jsonb也支 持索引,這也是一個(gè)令人矚目的優(yōu)勢(shì)(言外之意,json類型對(duì)索引程度不是特別友好)。

       由于json類型存儲(chǔ)的是輸入文本的準(zhǔn)確拷貝,其中可能會(huì)保留在語法 上不明顯的、存在于記號(hào)之間的空格,還有 JSON 對(duì)象內(nèi)部的鍵的順序。還有, 如果一個(gè)值中的 JSON 對(duì)象包含同一個(gè)鍵超過一次,所有的鍵/值對(duì)都會(huì)被保留( 處理函數(shù)會(huì)把最后的值當(dāng)作有效值)。相反,jsonb不保留空格、不 保留對(duì)象鍵的順序并且不保留重復(fù)的對(duì)象鍵。如果在輸入中指定了重復(fù)的鍵,只有 最后一個(gè)值會(huì)被保留。

2、項(xiàng)目開發(fā)中的選擇

        從數(shù)據(jù)插入更新處理速度上,json>jsonb。在數(shù)據(jù)查詢性能上jsonb>json。在數(shù)據(jù)的整體空間占用上,json>jsonb。

        因此,通常在一般的技術(shù)開發(fā)過程中,除非有特別特殊的需要(歷史遺留問題等),大多數(shù)應(yīng)用應(yīng)該 更愿意把 JSON 數(shù)據(jù)存儲(chǔ)為jsonb(通過json函數(shù)和函數(shù)索引的加持下,jsonb的查詢能力得到了大大的增強(qiáng))。

3、json數(shù)據(jù)類型

        在pg中的json數(shù)據(jù)類型可以分為:String,Number,boolean,Null。下面給出一個(gè)表格,是關(guān)于json的基本數(shù)據(jù)類型和pg數(shù)據(jù)類型的一個(gè)對(duì)比和對(duì)照。

JSON類型PG數(shù)據(jù)類型說明
Stringtext不允許\u0000,如果數(shù)據(jù)庫編碼不是 UTF8,非 ASCII Unicode 轉(zhuǎn)義也是這樣
NumberNumber不允許NaNinfinity
Booleanboolean只接受小寫truefalse拼寫
NULLSQL NULL是一個(gè)不同的概念

        這里關(guān)于編碼有一個(gè)需要解釋的地方,就是Unicode的轉(zhuǎn)義問題。這里涉及到數(shù)據(jù)庫在創(chuàng)建的時(shí)候是不是使用utf-8的編碼存儲(chǔ)。在json類型的輸入函數(shù)中,不管數(shù)據(jù)庫 編碼如何都允許 Unicode 轉(zhuǎn)義,并且只檢查語法正確性(即,跟在\u 后面的四個(gè)十六進(jìn)制位)。但是,jsonb的輸入函數(shù)更加嚴(yán)格:它不允 許非 ASCII 字符的 Unicode 轉(zhuǎn)義(高于U+007F的那些),除非數(shù)據(jù) 庫編碼是 UTF8。jsonb類型也拒絕\u0000(因?yàn)?PostgreSQL的text類型無法表示 它),并且它堅(jiān)持使用 Unicode 代理對(duì)來標(biāo)記位于 Unicode 基本多語言平面之外 的字符是正確的。合法的 Unicode 轉(zhuǎn)義會(huì)被轉(zhuǎn)換成等價(jià)的 ASCII 或 UTF8 字符進(jìn) 行存儲(chǔ),這包括把代理對(duì)折疊成一個(gè)單一字符。在把文本 JSON 輸入轉(zhuǎn)換成jsonb時(shí),RFC 7159描述 的基本類型會(huì)被有效地映射到原生的 PostgreSQL類型(如 上表描述)。因此,在合法 jsonb數(shù)據(jù)的組成上有一些次要額外約束,它們不適合 json類型和抽象意義上的 JSON,這些約束對(duì)應(yīng)于有關(guān)哪些東西不 能被底層數(shù)據(jù)類型表示的限制。尤其是,jsonb將拒絕位于 PostgreSQL numeric數(shù)據(jù)類型范 圍之外的數(shù)字,而json則不會(huì)。不過,實(shí)際上這類問題更可能發(fā)生在其他實(shí) 現(xiàn)中,因?yàn)榘?JSON 的number基本類型表示為 IEEE 754 雙精度浮點(diǎn) 是很常見的(這也是RFC 7159 明確期待和允許的)。當(dāng)在這類系 統(tǒng)間使用 JSON 作為一種交換格式時(shí),應(yīng)該考慮丟失數(shù)字精度的風(fēng)險(xiǎn)。

二、PG中json的簡單操作

1、基礎(chǔ)json數(shù)據(jù)操作

-- 簡單標(biāo)量/基本值
-- 基本值可以是數(shù)字、帶引號(hào)的字符串、true、false或者null
SELECT '5'::json;
 
-- 有零個(gè)或者更多元素的數(shù)組(元素不需要為同一類型)
SELECT '[1, 2, "foo", null]'::json;
 
-- 包含鍵值對(duì)的對(duì)象
-- 注意對(duì)象鍵必須總是帶引號(hào)的字符串
SELECT '{"name": "張三", "age": 39, "active": false,"sex":"男"}'::json;
 
-- 數(shù)組和對(duì)象可以被任意嵌套
SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;

2、json和jsonb輸出對(duì)比

SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
                      json                       
-------------------------------------------------
 {"bar": "baz", "balance": 7.77, "active":false}
(1 row)
 
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
                      jsonb                       
--------------------------------------------------
 {"bar": "baz", "active": false, "balance": 7.77}
(1 row)

        通過這里輸出可以看到,將目標(biāo)對(duì)象作為json輸出時(shí),輸出結(jié)果和輸入基本保持一致。 對(duì)于第二條語句而言,內(nèi)容上似乎沒有什么太大的變化,但是輸出結(jié)果的順序與第一條有明顯的區(qū)別。

再來看一組有意思的輸出,依然是關(guān)于jsonb和json的number結(jié)果的展示。

SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
         json          |          jsonb          
-----------------------+-------------------------
 {"reading": 1.230e-5} | {"reading": 0.00001230}
(1 row)

        很明顯的區(qū)別是jsonb被數(shù)據(jù)庫的執(zhí)行引擎給優(yōu)化了,展示結(jié)果與json也不同。

3、jsonb包含測(cè)試

        在很多的場(chǎng)景中,我們會(huì)使用API對(duì)兩個(gè)json進(jìn)行是否包含的判斷,因?yàn)樵趈son類型中,使用包含判斷也是比較耗費(fèi)時(shí)間的,在pg數(shù)據(jù)庫中,天然提供了數(shù)據(jù)庫層的包含函數(shù),以此來提高查詢匹配能力。在jsonb的查詢中,使用@>進(jìn)行包含的查詢操作。

-- 右邊具有一個(gè)單一鍵值對(duì)的對(duì)象被包含在左邊的對(duì)象中:
SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @> '{"version": 9.4}'::jsonb;
 
-- 右邊的數(shù)組不會(huì)被認(rèn)為包含在左邊的數(shù)組中,
-- 即使其中嵌入了一個(gè)相似的數(shù)組:
SELECT '[1, 2, [1, 3]]'::jsonb @> '[1, 3]'::jsonb;  -- 得到假
 
-- 但是如果同樣也有嵌套,包含就成立:
SELECT '[1, 2, [1, 3]]'::jsonb @> '[[1, 3]]'::jsonb;
 
-- 類似的,這個(gè)例子也不會(huì)被認(rèn)為是包含:
SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb;  -- 得到假
 
-- 包含一個(gè)頂層鍵和一個(gè)空對(duì)象:
SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"foo": {}}'::jsonb;

總結(jié)

以上就是本文的基本內(nèi)容,本文首先介紹了通用的json相關(guān)知識(shí),然后重點(diǎn)講述在PG中關(guān)于json類型的介紹,json和jsonb的區(qū)別,最后以案例的形式詳細(xì)說明json和jsonb的基本操作、輸出區(qū)別、包含測(cè)試等內(nèi)容,讓各位對(duì)json類型有一個(gè)基本直觀的認(rèn)識(shí),理解最基礎(chǔ)的數(shù)據(jù)庫操作。

到此這篇關(guān)于PostgreSQL中json數(shù)據(jù)類型的文章就介紹到這了,更多相關(guān)PostgreSQL json類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論