iT邦幫忙

2025 iThome 鐵人賽

DAY 10
1
Software Development

我所不知道的PostgreSQL 30天系列 第 10

Day 10: json 和 jsonb 資料型態的差異和索引

  • 分享至 

  • xImage
  •  

JSON 是目前常使用的資料格式之一,而 PostgreSQL 提供了兩種儲存 JSON 的資料型態,一個是 json ,一個是 jsonb

json 和 jsonb 的主要差別

jsonjsonb 這兩種格式的主要差別在於, json 會儲存原始的 JSON 字串, jsonb 會儲存解析過且轉成二進位格式的 JSON 。jsonb 因為需要解析和轉格式,在 INSERT 的時候速度會比 json 慢,但也因為解析過了,所以在查詢的時候,效能會比 json 好。

另外, jsonb 因為會把欄位是 number 型別的轉換成 PostgreSQL 的 numeric 型別(如下面圖片),所以格式和資料合法性的檢查會比 json 嚴謹。

也因為這樣, jsonb 會拒絕超出 numeric 範圍的數字,但 json 不會,如下面的範例。

CREATE TABLE test_numbers (
    js JSON,
    jsb JSONB
);

-- JSON 欄位可以成功
INSERT INTO test_numbers (js) VALUES ('{"big_num": 1e1000000000}');  -- 成功

-- JSONB 欄位會報錯
INSERT INTO test_numbers (jsb) VALUES ('{"big_num": 1e1000000000}');
-- 會出現錯誤訊息,例如:
-- ERROR: value overflows numeric format

關於 json 和 jsonb 的索引

在索引這一塊, jsonb 的支援比較好, jsonb 可以使用 GIN 這個索引,針對 JSON 中的其中一個欄位去做查詢, json 只能使用 BTReehash ,但這兩個索引僅拿「整個 JSON 字串」做比對,這對查詢的效能和應用上沒有太大幫助。

jsonb 之所以支援 GIN 這個索引,是因為 jsonb 可以使用 @>@? 這類的運算子進行查詢( json 不支援),而 GIN 有支援這些運算子,所以 jsonb 可以使用 GIN 這個索引進行優化。

CREATE TABLE test_json (
    id SERIAL PRIMARY KEY,
    data_json JSON,
    data_jsonb JSONB
);

INSERT INTO test_json (data_json, data_jsonb) VALUES 
('{"name": "Alice", "age": 30}', '{"name": "Alice", "age": 30}');
INSERT INTO test_json (data_json, data_jsonb) VALUES 
('{"name": "Alice2", "age": 32}', '{"name": "Alice2", "age": 32}');
INSERT INTO test_json (data_json, data_jsonb) VALUES 
('{"name": "Alice4", "age": 34}', '{"name": "Alice4", "age": 34}');

@> 為例,可以使用 SELECTWHERE 條件去查詢出 jsonb 中的欄位 age 值是32的資料。

如果是 json 的話,PostgreSQL 會噴出錯誤訊息。


上一篇
Day 9: 陣列資料型態
下一篇
Day 11: json 和 jsonb 如何處理 Unicode escape 字元?
系列文
我所不知道的PostgreSQL 30天30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言