SQL JSON 簡介

JSON (JavaScript Object Notation) 已經成為現代應用程式交換資料的事實標準。傳統的關聯式資料庫 (RDBMS) 雖然擅長處理結構化資料,但在面對格式多變或結構不明確的資料時,開發者往往需要不斷修改資料表架構 (Schema)。

為了解決這個痛點,主流資料庫如 MySQLPostgreSQLSQL Server 都陸續加入了對 JSON 的原生支援。這讓開發者能在同一個資料庫中同時享有「關聯式架構的嚴謹性」與「NoSQL 的靈活性」。

為什麼要在 SQL 中使用 JSON?

  1. 結構彈性 (Schema-less):不需要事先定義欄位,隨時可以增加或修改資料屬性,適合處理多變的設定檔或擴充屬性。
  2. 降低資料表爆炸:避免為了少數幾筆資料的特殊屬性而建立大量多餘的稀疏欄位 (Sparse Columns)。
  3. 減少連集 (JOIN):將相關但結構零散的資料直接以一個欄位儲存,減少執行 JOIN 的次數,提升讀取效率。
  4. 相容 Web 生態系統:現代 API 與前端應用多採用 JSON 格式,資料庫原生支援 JSON 可減少後端程式碼在物件與字串間轉換的負擔。

JSON vs. TEXT:有什麼差別?

你可能會問:「我直接把 JSON 字串存入一般的 TEXTVARCHAR 欄位不就好了嗎?」

雖然字串欄位可以存放 JSON,但使用資料庫原生的 JSON 資料型態有以下關鍵優勢:

  • 自動校驗 (Data Validation):當你新增或更新資料時,資料庫會自動檢查內容是否符合正確的 JSON 語法。如果是錯誤的格式,會直接報錯攔截。
  • 優化儲存空間:資料庫內部會將 JSON 轉換為二進位格式 (如 MySQL 的變種 BSON),這比純文字佔用更小的空間,且有利於快速讀取。
  • 高效存取:不需要先取出整串字串再解析。資料庫可以直接搜尋內部的屬性,甚至為特定路徑建立索引。

JSON 路徑表達式 (Path Expressions)

要在 SQL 中操作 JSON 資料,最核心的概念就是 JSON 路徑 (JSON Path)。它類似於檔案路徑,用來指定我們想讀取的具體節點。

基本符號

  • $:代表整個 JSON 文件的根節點。
  • .:用來選取物件中的屬性欄位。
  • []:用來選取陣列中的元素索引 (從 0 開始)。
  • *:代表通配符,選取該層級下的所有屬性或元素。

範例說明

假設有一筆 JSON 資料如下:

{
    "user": "Mike",
    "scores": [95, 88, 100],
    "address": { "city": "Taipei", "zip": "100" }
}

其對應的路徑為:

  • $.user → 輸出 "Mike"
  • $.scores[0] → 輸出 95
  • $.address.city → 輸出 "Taipei"
  • $.address.* → 輸出 ["Taipei", "100"]

如何檢查資料是否為 JSON?

我們可以使用 IS JSON (SQL 標準語法) 來驗證特定欄位或字串是否為正確格式。

SELECT '{"name": "Mike"}' IS JSON; -- 回傳 1 (MySQL) 或 TRUE

這在批次寫入資料時非常有用,可以確保進來的資料品質:

不同的資料庫對 JSON 的支援細節略有不同:

  • MySQL (5.7+):支援原生 JSON 型態,提供 -> 語法。
  • PostgreSQL:提供 json 與更強大的 jsonb (二進位存取,支援索引)。
  • SQL Server (2016+):尚無原生 JSON 欄位型態,但提供豐富的 JSON 函數來處理 NVARCHAR 欄位中的 JSON 字串。