PostgreSQL 提供了兩種 JSON 數據類型:JSON 以及 JSONB。這兩種類型主要的區別在于數據存儲格式,JSONB 使用二進制格式存儲數據,更易于處理。
PostgreSQL 推薦優先選擇 JSONB 數據類型。
兩種數據類型之間的區別:
功能 | JSON | JSONB |
---|---|---|
存儲格式 | 字符串原文存儲 | 解析后的二進制 |
全文索引 | 不支持 | 支持 |
保留空白符 | 保留 | 不保留 |
保留鍵的順序 | 保留 | 不保留 |
保留重復鍵 | 保留 | 不保留 |
由于存儲格式的不同,JSONB 輸入時稍微慢一些(需要轉換),但是查詢時快很多。
接下來的內容主要使用 JSONB 數據類型,但是大部分功能也可以使用 JSON 數據類型。
一、創建并插入數據
CREATE TABLE product (id INTEGER NOT NULL PRIMARY KEY,name VARCHAR(100),attr1 JSONB,attr2 JSON
);
1. 插入數據:
INSERT INTO product
VALUES( 1, '阿莫西林', '{"code": "100011","price": 18,"uom": "盒","specification": "10粒/盒","price": 18.00}','{"code": "100011","price": 18,"uom": "盒","specification": "10粒/盒","price": 18.00}');INSERT INTO product
VALUES( 2, '阿司匹林', '{"code": "100013","price": 28,"uom": "盒","specification": "20粒/盒","price": 28.00}','{"code": "100013","price": 28,"uom": "盒","specification": "20粒/盒","price": 28.00}');
?2. 查詢數據:
從紅框中內容可以看出來兩種類型的區別:JSON保留原格式,JSONB不做保留,具體見上邊的表格。
3. 格式化方法插入:
jsonb_build_object、json_build_object?函數可以通過一系列輸入創建JSON 對象
INSERT INTO product
VALUES( 3, '農夫山泉', jsonb_build_object ( 'code', '100015', 'price', 3 ), json_build_object ( 'code', '100015', 'price', 3 ) );
其他常用的構建 JSON 數據的函數如下:
to_json 以及 to_jsonb
array_to_json
row_to_json
json_build_array 以及 jsonb_build_array
json_object 以及 jsonb_object
具體操作可以參考:PostgreSQL操作json/jsonb方法詳解_PostgreSQL_腳本之家
這些方法看完還是覺得直接輸入來的簡單方便,也可能我沒有領略到精髓。
二、查詢JSON字段及屬性(下邊都以JSONB的格式)
?1. 查詢JSON字段:
product=# select * from product where id =3 ;id | name | attr1 | attr2
----+----------+--------------------------------+----------------------------------3 | 農夫山泉 | {"code": "100015", "price": 3} | {"code" : "100015", "price" : 3}
(1 row)product=# select name, attr1, attr2 from product where id =3 ;name | attr1 | attr2
----------+--------------------------------+----------------------------------農夫山泉 | {"code": "100015", "price": 3} | {"code" : "100015", "price" : 3}
(1 row)
2.?獲取JSON單個屬性
查詢attr1下的code屬性,
運算符 -> 可以通過指定節點的鍵獲取相應的數據。這種方法返回的數據仍然是 JSON 類型,使用雙引號包含。
如果想要以字符串形式返回節點中的數據值,可以使用運算符 ->>。如:
如果查詢的 JSON 節點不存在,將會返回空值:
3. 獲取JSON數組屬性
第二個 -> 運算符返回了該屬性中的第 1 個數組元素(數組下標從 0 開始)。
注意這里第一個不能使用“ ->>”,轉成字符串之后就沒法再往下獲取元素了。
運算符 #> 以及 #>> 可以通過指定 JSON 節點的路徑獲取嵌套屬性,路徑可以包含鍵的名稱或者數組元素下標,返回類型分別為 JSON 和字符串。
4. 基于JSON數據的過濾
直接以屬性作為條件進行查詢:這種無法根據屬性進行匹配,
?如果要匹配就需要用以下方式:
需要注意的是->是json格式,-->是字符,需要注意匹配,如元素屬性為數字,則需要轉換后對比:
5. JSON 轉換為數據行
PostgreSQL 支持將 JSON 字段轉換為數據行格式。例如,jsonb_each 函數可以將每個鍵值對轉換為一個記錄:
與此類似的函數還有:
json_each 以及 json_each_text
json_array_elements 以及 json_array_elements_text
jsonb_array_elements 以及 jsonb_array_elements_text
6. 獲取所有JSON的key
7. 判斷JSON屬性是否存在
PostgreSQL 還提供了一些用于判斷 JSON 屬性是否存在的運算符,例如 ? 運算符。
三、更新 JSON 字段數據
1. || 運算符
使用 UPDATE 語句更新 JSON 字段時,可以通過 || 運算符將新的鍵值增加到已有 JSON 數據。例如:
JSONB格式沒有順序
2.?jsonb_insert 方法
利用 jsonb_insert 方法,例如:
3. jsonb_set 方法
如果想要更新已有鍵的數值,可以使用 jsonb_set 函數。例如:
如果沒有key則新增:
?
四、刪除 JSON 字段數據
1. 刪除整個 JSON 字段數據可以簡單地將其設置為 NULL,例如:
2.?刪除 JSON 字段中的某個屬性可以使用 - 運算符,例如:
當沒有元素屬性時,不會刪除報錯。
五、全文索引
PostgreSQL 提供了支持 JSON 字段的全文索引,可以優化查詢的性能。這種索引的類型為 GIN(通用倒排索引),通常用于搜索引擎。
CREATE INDEX index_product_att1 ON product USING GIN(attr1);
attr1時JSONB類型,而atttr2是JSON類型,創建索引會報錯,這個差異對應了上邊表格
以上基本是暫時了解到的內容,歡迎交流斧正!!!