JSON (JavaScript Object Notation) 是一種很流行的資料格式,常拿來在系統之間交換資料。它很輕量、人類也看得懂,超適合拿來表示像物件或陣列這種結構化資料。
PostgreSQL 支援兩種 JSON 相關的資料型別:
JSON:把資料存成字串。這就是純文字的 JSON,沒有做什麼內部優化。JSONB:JSON 的二進位表示法。這個讀取、篩選、處理都比較快,因為 PostgreSQL 會先把 JSON 解析好再存起來,還會優化存法。
為什麼大家比較常用 JSONB?因為:
- 它用二進位存,查詢速度比較快。
- 可以被索引,超適合大資料集。
- 會自動把 key 排好順序、重複的會去掉,處理起來比較方便。
JSON 結構範例:
{
"name": "Alice",
"age": 25,
"skills": ["SQL", "PostgreSQL", "JSONB"]
}
為什麼 JSONB 很好用?
存半結構化資料。 現實世界的資料常常是很複雜的物件(像是 metadata、設定、使用者 profile 之類)。JSONB 讓你可以直接存,不用搞一堆 table 跟關聯。
資料結構常變也沒差。 如果物件的欄位常常加加減減(像是 profile 有時多一個欄位、有時少一個),JSONB 超彈性,直接存就好。
跟 API 打交道超方便。 很多 web app 都是用 JSON 傳資料。你不用先轉格式,直接存起來,想怎麼查就怎麼查。
建立有 JSONB 欄位的資料表
來點實作吧!假設我們要做一個用來存使用者 profile 的資料庫。
profile 這個欄位會存所有額外資訊(像年齡、興趣、聯絡方式),格式就是 JSON。這樣每個使用者的資料結構不一樣也沒關係。
| id | name - VARCHAR(100) | profile - JSONB |
|---|---|---|
| 1 | Alice | {"age": 25, "skills": ["SQL", "PostgreSQL", "JSONB"], "location": "New York"} |
| 2 | Bob | {"age": 30, "interests": ["hiking", "photography"], "location": "Denver"} |
| 3 | Charlie | {"email": "charlie@example.com", "verified": true} |
| 4 | Diana | {"age": 22, "skills": ["Python"], "bio": "Data enthusiast", "location": "Berlin"} |
| 5 | Eve | {"age": 28, "skills": [], "preferences": {"theme": "dark", "notifications": false}} |
JSON 資料可以直接當字串插進去。PostgreSQL 會自動幫你轉成 JSONB。
從 JSONB 撈資料
有資料之後,來看看怎麼查。PostgreSQL 給你一堆 operator 可以玩 JSONB。
抓欄位值
用 -> operator 來拿欄位的值:
-- 顯示使用者年齡
SELECT profile->'age' AS age FROM users;
把值轉成字串
->> operator 可以直接拿到字串:
-- 顯示使用者所在地
SELECT profile->>'location' AS location FROM users;
用 JSONB 做資料篩選
JSONB 最強的地方就是查詢跟篩選。你可以用標準 SQL operator 來玩 JSON。
依 key 篩選範例:
-- 找出住在 "New York" 的使用者
SELECT * FROM users
WHERE profile->>'location' = 'New York';
查陣列內容
JSON 支援陣列,PostgreSQL 也可以查陣列裡有沒有某個值:
-- 找會 SQL 的使用者
SELECT * FROM users
WHERE 'SQL' = ANY(jsonb_array_elements_text(profile->'skills'));
jsonb_array_elements_text 這個 function 會把陣列元素變成字串,這樣你就可以比對了。
還有更短的寫法,用 @> operator:
-- 找會 SQL 的使用者
SELECT * FROM users
WHERE profile->'skills' @> '["SQL"]';
更多 JSON 的 function 跟用法我們之後還會聊,等你學到那邊再說 :P
重點整理:什麼時候該用 JSONB
JSONB 超適合:
- 存很複雜的結構化資料。
- 處理外部 API 來的資料。
- 物件結構常常變動的情境。
不過要注意,JSONB 用太多會讓索引跟資料庫管理變麻煩。如果你的資料結構很穩定,還是用關聯式資料表比較好。
GO TO FULL VERSION