SQL vs NoSQL:你個 App 應該用邊種數據庫?
SQL 數據庫(亦稱關聯式數據庫)將數據存放喺有固定結構嘅數據表入面,即行同欄,並將相關嘅數據表連結一齊。你用 SQL 語言查詢佢哋。Postgres、MySQL 同 SQLite 都係例子。NoSQL 數據庫則用其他方式儲存數據,例如文件、鍵值配對、寬欄或圖形,通常容許較靈活嘅結構。MongoDB、Redis、DynamoDB 同 Firestore 都係例子。對大部分商業 App 嚟講,SQL 數據庫係較明智嘅預設選擇;NoSQL 則適合特定用途。
為何用 AI 建 App 時呢個選擇咁重要
數據庫係 App 入面日後最難更改嘅部分之一。畫面半日就可以重新設計;但要將多年嘅客戶數據遷移去另一種數據庫,就係一個專案。
當 AI App 建構工具幫你加入數據儲存,佢就係喺呢啲選項之中揀一個。明白其中分別有助你:
- 了解你嘅數據係點樣,以及佢能否回答你日後會問嘅問題(「按月按產品計嘅收入」)。
- 評估平台嘅選擇。 有啲平台建基於文件數據庫,有啲則建基於關聯式數據庫。常見例子可以睇 Supabase vs Firebase。
- 避免被綁死。 SQL 係共通標準,所以關聯式數據一般比較容易喺不同供應商之間搬遷。
日常生活嘅比喻
SQL 數據庫好似一組設計得好仔細、欄位嚴格嘅試算表:一張表放客戶,一張表放訂單,每一行訂單都透過 ID 指向一行客戶。表入面每一行都有相同嘅欄。要花少少心思去規劃,但跨表提問好容易,數據亦會保持整齊。
NoSQL 文件數據庫則好似一個放滿資料夾嘅檔案櫃。每位客戶嘅資料夾可以將佢嘅資料同訂單一次過放埋一齊,而某個資料夾亦可以放入其他資料夾冇嘅額外文件。要攞一位客戶嘅完整資料好快。但如果要回答「上個月每個人買咗啲乜」,就要打開好多資料夾。
真正嘅分別
| SQL(關聯式) | NoSQL | |
|---|---|---|
| 數據形態 | 有固定欄位嘅數據表 | 文件、鍵值、寬欄或圖形 |
| 結構 | 預先定義結構,透過遷移更改 | 通常較靈活;結構如有,多由應用程式碼執行 |
| 關係 | 內置:外鍵同連接 | 通常透過巢狀數據或應用程式碼處理 |
| 查詢語言 | SQL,共通標準 | 每個產品各不相同 |
| 一致性 | 強交易係標準配備 | 視乎產品同設定而異;而家好多都提供交易功能 |
| 擴展 | 傳統上係向上擴展(更大部伺服器);向外擴展可行但較難 | 好多係為分散喺多部伺服器而設計 |
| 擅長 | 商業數據、報表,任何關係複雜嘅數據 | 大量簡單記錄、快取、靈活內容 |
| 例子 | Postgres、MySQL、SQLite、SQL Server | MongoDB、Redis、DynamoDB、Firestore、Cassandra、Neo4j |
「NoSQL」並非單一種技術。主要類別如下:
| 類別 | 儲存數據嘅方式 | 常見用途 |
|---|---|---|
| 文件(MongoDB、Firestore) | 類 JSON 文件 | 內容、目錄、記錄多樣嘅 App |
| 鍵值(Redis、DynamoDB) | 用鍵查找嘅值 | 快取、工作階段、計數器 |
| 寬欄(Cassandra) | 欄位組合靈活嘅行 | 寫入密集嘅大型數據集 |
| 圖形(Neo4j) | 節點同連線 | 社交網絡、推薦 |
實例:同一批店舖數據,兩種做法
以一間細小網上店舖為例,有一位客戶同她嘅訂單。
SQL(關聯式): 數據分拆成數據表,並透過 ID 互相連結。
-- customers: id=1, name='Lena Ortiz'
-- orders: id=101, customer_id=1, total=42.00
-- id=103, customer_id=1, total=25.00
SELECT c.name, SUM(o.total)
FROM customers c JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
如果 Lena 更改電郵,只需要喺一個地方更改。要問「本月每位客戶嘅總銷售額」,只需一個查詢。
NoSQL(文件): 佢嘅訂單可以直接放喺佢自己嘅文件入面。
{
"_id": "cust_1",
"name": "Lena Ortiz",
"email": "lena@example.com",
"orders": [
{ "id": 101, "total": 42.00, "items": ["Green tea"] },
{ "id": 103, "total": 25.00, "items": ["Teapot"] }
]
}
載入 Lena 嘅個人頁面連同所有訂單,只需一次讀取。但跨越所有客戶嘅問題,例如本月最暢銷產品,就需要更多工夫;而且如果同一個產品詳情被複製到好多訂單入面,保持同步就會變成 App 嘅責任。
兩者都冇對錯,關鍵在於你嘅 App 最常用邊種模式。
點樣選擇
如果有以下情況,關聯式 SQL 數據庫通常係正確嘅預設選擇:
- 你嘅數據關係複雜:用戶、團隊、預約、發票、產品。
- 你需要跨記錄嘅報表、篩選同總計。
- 準確性十分重要:金錢、庫存水平、權限。
如果有以下情況,就值得考慮 NoSQL 數據庫:
- 你需要快速嘅快取或工作階段儲存 — Redis 好常用,通常會與 SQL 數據庫並存。
- 你嘅記錄數量龐大、簡單而且互相獨立,例如事件日誌或感應器讀數。
- 你使用嘅平台係圍繞某種 NoSQL 而建,例如 Firebase 嘅 Firestore,而其即時功能正係主要吸引之處。
好多 App 會兩樣都用:以 SQL 作為主要數據來源,再以 NoSQL 儲存作快取或特定功能。
重要詞彙
| 詞彙 | 意思 |
|---|---|
| 關聯式數據庫 | 由相互連結嘅數據表組成嘅 SQL 數據庫。 |
| 結構(Schema) | 數據嘅既定結構。 |
| 連接(Join) | 喺一個查詢中合併兩張數據表嘅相關行。 |
| 文件 | 文件數據庫入面一筆獨立、類 JSON 嘅記錄。 |
| 反正規化(Denormalisation) | 將數據複製到多個位置,以加快讀取。 |
| ACID | 保證交易可靠嘅特性:全部成功或全部失敗、一致、隔離同持久。 |
| 水平擴展 | 將數據分散到多部伺服器,而唔係用一部更大嘅伺服器。 |
常見誤解
- 「NoSQL 即係冇結構。」 你嘅數據一定有某種形態。用 NoSQL 時,數據庫可能唔會強制執行,所以要由你嘅程式碼負責。
- 「SQL 唔可以擴展。」 關聯式數據庫可以運行非常龐大嘅服務。大部分 App 根本未接近其上限。
- 「NoSQL 永遠較快。」 只限於佢設計嘅模式。跨越多方面嘅報表可能反而較慢。
- 「一定要永遠揀一種。」 好多 App 會將兩者結合。而且 Postgres 等 SQL 數據庫亦會儲存 JSON,所以幾個靈活欄位並不需要 NoSQL。
- 「NoSQL 即係唔可以用 SQL。」 呢個名稱通常理解為「不僅限於 SQL」,而部分 NoSQL 產品亦提供類 SQL 嘅查詢語言。
可以問你嘅 AI 建構工具嘅問題
- 「呢個 App 用邊種數據庫?點解佢適合我嘅數據?」
- 「請畫出數據表或集合,以及佢哋之間嘅關係。」
- 「六個月後我會想要邊啲報表?呢個數據庫可以容易咁回答嗎?」
- 「如果有幾個欄位真係好靈活,就將佢哋以 JSON 形式儲存喺 Postgres 入面,而唔係再加一個數據庫。」
- 「只有喺確定有速度問題時先加快取。」
Mythex 嘅數據庫
Mythex 為每個需要數據庫嘅專案提供一個專用嘅 Postgres 數據庫(一個關聯式 SQL 數據庫)。當 App 有需要時,你可以喺對話中要求加入,或者用 /database 指令加入(Database)。咁樣適合大部分商業 App:用戶、預約、訂單同報表。如果你需要某個外部服務,例如託管嘅文件數據庫,agent 可以寫程式碼連接佢,而所需嘅金鑰會以專案機密形式儲存。如果想進一步了解語言本身,請閱讀 SQL 係咩。
常見問題
SQL 同 NoSQL 嘅主要分別係咩?
SQL 數據庫將數據存放喺有固定結構嘅數據表入面,並會將相關嘅數據表連結一齊,你用 SQL 語言查詢。NoSQL 數據庫則採用其他模式,例如文件、鍵值配對、寬欄或圖形,通常容許較靈活嘅結構,而每個產品都有自己嘅查詢方法。
NoSQL 一定比 SQL 快咩?
一般嚟講唔係。兩者都係為自己設計嘅存取模式而快。鍵值儲存用鍵提取單一項目非常快;關聯式數據庫則擅長篩選、連接同總結相關數據。設計同索引比類別更加重要。
對初創公司或小型 App 嚟講,邊種較好?
大部分商業 App,例如客戶、訂單、預約、用戶同權限,關聯式 SQL 數據庫(例如 Postgres)係穩陣嘅預設選擇。NoSQL 適合特定需要,例如快取、某些平台嘅即時同步,或者大量簡單、獨立嘅記錄。
MongoDB 係 SQL 定係 NoSQL?
MongoDB 係 NoSQL 文件數據庫。佢以靈活嘅類 JSON 文件儲存記錄,而唔係以數據表入面嘅行來儲存。
SQL 數據庫可唔可以儲存 JSON?
可以。Postgres 有 jsonb 類型,用於儲存同查詢 JSON,MySQL 同 SQLite 亦支援 JSON。咁樣好多 App 可以保留關聯式嘅核心,再加上幾個靈活欄位,唔需要另外一個 NoSQL 數據庫。