iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
自我挑戰組

三十天,PG與我系列 第 30

在PostgreSQL使用JSON型態欄位

  • 分享至 

  • xImage
  •  

JSON是當前網路上面傳遞key-value pair蠻流行的資料格式,如果想要在Postgres資料庫上面存放JSON的資料型態的話,Postgres有提供一些適合表示JSON的資料型態:

1.hstore:單純的key-value格式,功能陽春,無法呈現JSON物件的巢狀結構
2.JSON:可以理解成以文字的形式記錄JSON
3.JSONB:為JSON最佳化的資料格式,可以支援index以及JSON物件巢狀結構的表示

JSONB資料型態的使用

參考資料:
https://www.pg4e.com/lectures/06-JSON.php

將JSON的資料插入jsonb欄位裡面,可以透過將字串轉型成jsonb的方式。

INSERT INTO swapi (body) 
SELECT ('{ "type": "Neon", "series": "24 Hours of Lemons", "number": ' || generate_series(1000,5000) || '}')::jsonb;

JSONB的查詢,可以透過'->>' operator取得json中特定key的欄位文字(資料型態為text),若是要取出數字需要將->> operator包進括號然後轉型成數字。
例子:
透過json欄位的name屬性之數值來篩選資料

SELECT COUNT(*) FROM jtrack WHERE body->>'name' = 'Summer Nights';

如果要查找jsonb欄位的內容是否包含某個key-value pair,可以透過"@>"operator

SELECT COUNT(*) FROM jtrack WHERE body @> '{"name": "Summer Nights"}';

單純查找jsonb欄位是否有特定的key,可以使用"?"operatpor

--測試"favorite"key是否存在json欄位中
SELECT COUNT(*) FROM jtrack WHERE body ? 'favorite';

如果要將額外的key加入json欄位的紀錄,可以透過"||"operator來達成

UPDATE jtrack SET body = body || '{"favorite": "yes"}' WHERE (body->'count')::int > 200;

至於更新jsonb欄位中key的數值,可以使用jsonb_update的function

UPDATE jtrack SET body = jsonb_set(body, '{ count }', ( (body->>'count')::int + 1 )::text::jsonb )
WHERE body->>'name' = 'Summer Nights';

Index的使用

jsonb欄位可以使用b-tree或是GIN index來檢索內容。
B-tree index可以用來對json的某一支key做索引,GIN index可以用來快速檢查jsonb欄位是否存在某個key,而透過GIN index在jsonb_path_ops上面建立索引可以幫助掃描任意的key_value pair組合(上面提過的@> operator)。

CREATE INDEX jtrack_btree ON jtrack USING BTREE ((body->>'name'));
CREATE INDEX jtrack_gin ON jtrack USING gin (body);
CREATE INDEX jtrack_gin_path_ops ON jtrack USING gin (body jsonb_path_ops);

上一篇
Postgres平行化query執行
系列文
三十天,PG與我30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言