資料庫層級結構:Database、Schema、Table 的關係與應用
更新日期: 2025 年 3 月 20 日
本文為 SaaS 架構基礎,第 3 篇:
- 網站入門指南:認識站點(Site)的概念與應用
- 網站前台與後台:初學者指南
- 資料庫層級結構:Database、Schema、Table 的關係與應用 👈進度
- 多租戶 SaaS 架構完整指南:從概念到技術實現
在資料庫管理中,數據的組織方式直接影響到系統的可擴展性與安全性。
當我們查詢資料時,經常會遇到類似以下的 SQL 語法:
SELECT * FROM companyA.employees;
這樣的寫法代表我們正在查詢 Schema(綱要) companyA
內的 employees
表格(Table)。
這種層級結構在 PostgreSQL、SQL Server 以及部分 MySQL 應用場景 中非常常見,特別適用於 多租戶(Multi-Tenant)系統,例如 SaaS(Software as a Service) 平台。
為了更清楚地理解這種結構,我們將從資料庫的層級架構出發,逐步介紹 Database → Schema → Table 的概念,以及它們在多租戶環境中的應用方式。
資料庫的層級架構
在 關聯式資料庫管理系統(RDBMS,Relational Database Management System) 中,數據的組織方式遵循明確的層級結構,以確保高效管理、權限控管以及查詢性能的優化。
這種層級化設計讓開發者能夠清楚地區分不同層次的數據,從最上層的 資料庫(Database) 到中間的 Schema(綱要),再到最底層的 資料表(Table)。
這種結構的核心目標是 提供良好的數據隔離、管理便利性與安全性,特別是在 多租戶架構(Multi-Tenant Architecture) 下,Schema 的應用可以有效幫助企業將不同租戶的數據進行分區管理。
Database(資料庫)
Database 是整個資料存儲體系的「最高層級」,它負責管理所有的 Schema、Table、索引(Indexes)、儲存空間 以及 存取權限。
可以把 Database 想像成一個大型的「檔案夾」,裡面存放了許多 Schema,而 Schema 內又包含了各種 Table,用來儲存實際的業務數據。
在實務應用中,一個 Database 通常對應一個業務應用系統。
例如:
- 電商平台的 Database:管理所有商品、訂單、用戶數據。
- 人資管理系統的 Database:管理員工資訊、薪資發放、考勤記錄。
- SaaS 平台的 Database:儲存多家企業的數據,每家企業擁有一個獨立的 Schema。
📌 範例:假設我們正在開發一個 SaaS 平台,我們可以建立一個名為 SaaS_DB
的資料庫,作為系統內所有企業數據的主要存儲空間。
CREATE DATABASE SaaS_DB;
Schema(綱要)
Schema 是 Database 內的邏輯分區(Logical Partition),負責 組織與隔離數據,讓數據管理更加有條理。
在一些支援 Schema 的資料庫系統(如 PostgreSQL、SQL Server)中,每個 Schema 相當於一個獨立的命名空間(Namespace),它可以包含多張 Table、索引、視圖(Views)等物件。
這讓我們能夠有效地將數據進行分類管理,例如:
- 在多租戶架構(Multi-Tenant Architecture)下,每個租戶的數據可以存放在獨立的 Schema 內,例如
companyA
、companyB
。 - 在大型企業系統中,可以透過 Schema 區分不同業務領域的數據,例如
HR(人資)
、Sales(銷售)
、Finance(財務)
。
📌 Schema 的優勢:
✅ 數據隔離:確保不同企業或業務的數據不會互相影響。
✅ 權限管理:可以針對不同的 Schema 設定不同的存取權限,提高數據安全性。
✅ 避免命名衝突:不同 Schema 內可以擁有相同名稱的 Table,例如 companyA.employees
和 companyB.employees
,而不會互相衝突。
📌 範例:在 SaaS_DB
資料庫內,為不同企業建立獨立的 Schema:
CREATE SCHEMA companyA;
CREATE SCHEMA companyB;
這樣,每個企業都擁有自己的命名空間,確保數據的邏輯隔離。
Table(資料表)
Table(資料表) 是 存放具體數據的最小單位,所有的業務數據最終都會儲存在 Table 內。
Table 由 欄位(Columns) 和 記錄(Rows) 組成,每個欄位定義了一個屬性,而每一筆記錄則是具體的數據。
在一個企業的 Schema 內,可能包含多張不同的 Table,例如:
employees
(員工表):存放員工的基本資訊(如姓名、職稱、薪資)。payroll
(薪資表):記錄員工的薪資發放情況。attendance
(考勤表):記錄員工的打卡與出勤狀況。
📌 範例:在 companyA
Schema 內建立 employees
資料表:
CREATE TABLE companyA.employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
position VARCHAR(50),
salary DECIMAL(10,2)
);
這樣的設計讓 companyA
擁有自己的 employees
表,而 companyB
也可以有相同名稱但完全獨立的表格 companyB.employees
,確保數據的邏輯隔離。
資料層級結構範例
假設我們有一個 SaaS 平台,提供給不同企業使用,我們可以將數據組織成以下結構:
Database: SaaS_DB
├── Schema: companyA
│ ├── Table: employees
│ ├── Table: payroll
│ ├── Table: attendance
├── Schema: companyB
│ ├── Table: employees
│ ├── Table: payroll
│ ├── Table: attendance
在這樣的設計中:
SaaS_DB
是 Database(資料庫),存放所有企業的數據。companyA
、companyB
是 Schema(綱要),確保不同企業的數據邏輯隔離。employees
、payroll
、attendance
是 Table(資料表),存放具體的員工資訊、薪資數據和考勤記錄。
📌 查詢某家企業的員工數據 假設我們要查詢 公司 A 的員工資訊,可以使用以下 SQL 指令:
SELECT * FROM companyA.employees;
這種查詢方式可以確保:
- 不同企業的數據互不影響,即使執行錯誤的 SQL 也不會影響其他租戶的數據。
- 無需額外的
tenant_id
欄位來區分租戶,減少 SQL 錯誤帶來的風險。
如果沒有使用 Schema,而是讓所有租戶的數據存放在同一張 employees
表中,就必須依賴 tenant_id
來區分,例如:
SELECT * FROM employees WHERE tenant_id = 'A';
但這種方式容易因 遺漏 WHERE 條件 而誤查詢到其他租戶的數據,因此 Schema 的應用能夠有效提高數據的安全性與管理便利性。
Schema 在多租戶系統的應用
在 SaaS 服務 中,系統通常需要支援多個企業(租戶),而 Schema 是常見的數據隔離方案之一。
假設我們的 SaaS 平台提供人資管理系統,並使用「共享資料庫,獨立 Schema」架構,那麼每個企業的 employees
表可能如下:
🔹 公司 A 的員工表 (companyA.employees
)
id | name | position | salary |
---|---|---|---|
1 | Alice | Manager | 80000 |
2 | Bob | Engineer | 70000 |
🔹 公司 B 的員工表 (companyB.employees
)
id | name | position | salary |
---|---|---|---|
1 | Charlie | HR | 60000 |
2 | David | Sales | 65000 |
使用 SQL 查詢
當某家企業的管理員查詢員工數據時,可以這樣執行:
-- 查詢公司 A 的員工
SELECT * FROM companyA.employees;
-- 查詢公司 B 的員工
SELECT * FROM companyB.employees;
這樣的設計讓不同公司的數據完全分開,即使不小心執行錯誤的 SQL,也不會存取到其他租戶的數據。
另一種方式:共享 Table + tenant_id
另一種多租戶數據管理方式是讓所有企業共用同一張表,並透過 tenant_id
來區分:
SELECT * FROM employees WHERE tenant_id = 'A';
但這種方式有潛在風險:
- 可能誤查詢其他租戶數據:如果
WHERE
條件寫錯,可能會取到其他企業的數據。 - 權限管理較為複雜:需要額外的機制來確保不同租戶無法存取對方的數據。
因此,當租戶數量較少且數據隔離需求高時,Schema 隔離是一個更好的選擇。
什麼時候適合使用「Schema 隔離」?
在設計多租戶(Multi-Tenant)架構時,如何管理不同租戶的數據是一個關鍵問題。
Schema 隔離(Schema Isolation) 是一種常見的解決方案,它允許每個租戶擁有獨立的 Schema,確保數據的邏輯隔離。
然而,這種方法並不適用於所有場景,選擇是否使用 Schema 需要考慮系統的規模、數據管理需求以及性能影響。
以下是適合與不適合使用 Schema 隔離 的情境分析,幫助開發者選擇最合適的數據存儲策略。
適合使用 Schema 隔離的情境
1️⃣ 中小型 SaaS 企業,租戶數量在 1000 個以內
Schema 隔離適合 租戶數量中等 的 SaaS 企業,例如擁有數百到上千家客戶,但尚未達到大規模的程度(如數萬家以上)。
- 原因:
- 當租戶數量適中時,管理獨立 Schema 的開銷仍在可接受範圍內,不會對資料庫伺服器造成過度負擔。
- 可以確保不同租戶的數據完全隔離,增強數據安全性與隱私性。
📌 範例:
一間提供 人資管理系統(HRM SaaS) 的公司,客戶數約 500 家企業,每家企業的數據規模不大(數萬筆員工紀錄以內)。
此時,使用 Schema 隔離能確保每個客戶的數據互不影響,且管理負擔仍可控制。
2️⃣ 需要一定程度的數據隔離,但仍希望共用相同的資料庫資源
在某些應用場景下,數據隔離是必要的,但完全獨立的資料庫又過於昂貴與難以管理。此時,Schema 隔離是一個很好的折衷方案。
- 與「獨立資料庫」相比,Schema 隔離可以降低基礎設施成本,因為所有租戶仍共用同一個 Database。
- 與「共享 Table」相比,Schema 隔離能有效防止租戶數據誤查詢的風險(如開發者錯誤地漏加
WHERE tenant_id = X
條件)。
📌 範例:
一間 法務文件管理 SaaS 平台,提供給不同律師事務所使用。
由於每家律所的數據涉及機密性,不能讓租戶間的數據存放在同一張表,但又不希望為每家租戶建立獨立資料庫,這時候 Schema 隔離能達到兼顧安全與資源共享的平衡點。
3️⃣ 每個租戶的數據結構可能有些許不同
某些租戶可能需要自訂數據結構,例如:
- A 企業需要額外的欄位(如
bonus_percentage
獎金比例)。 - B 企業需要更多自訂屬性(如
contract_type
合約類型)。
在「共享 Table + tenant_id
」的架構下,所有租戶都共用相同的 Table,因此每次新增租戶自訂欄位時,都需要修改 全域資料表結構,導致:
- 表結構過於複雜,無法維護。
- 不必要的空欄位(其他租戶不需要的欄位佔用空間)。
- 查詢效率下降(Table 變得過於寬大)。
📌 範例:
一間 客製化 CRM(客戶關係管理)SaaS 公司,不同客戶的 CRM 需求不同:
- 租戶 A 需要記錄客戶的「購買歷史」。
- 租戶 B 需要額外的「信用評分」欄位。
- 租戶 C 則希望有「社交媒體互動記錄」。
如果所有租戶共用同一張 customers
表,會導致許多不必要的空欄位,而 Schema 隔離則可以讓每個租戶的表格根據需求靈活設計。
不適合使用 Schema 隔離的情境
1️⃣ 租戶數量極大(如幾萬家以上)
如果租戶數量極大,例如 數萬家企業或更多,使用 Schema 隔離可能會導致 管理負擔過重,主要問題包括:
- 資料庫管理複雜度增加:每個 Schema 內都有獨立的 Table,當 Schema 數量過大時,管理變得困難。
- 系統效能影響:大部分 RDBMS(如 PostgreSQL)在有過多 Schema 時,可能會影響效能,特別是當查詢涉及跨 Schema 時。
- 備份與維護難度提升:需要針對數千、數萬個 Schema 進行備份與維護,運營成本大幅提高。
📌 替代方案:
對於 超大規模租戶數量(幾萬家以上),建議考慮:
- 共享 Table +
tenant_id
(適用於數據結構統一的情境)。 - 獨立 Database(適用於大型租戶,確保數據完全隔離)。
📌 範例:
- 某電商平台擁有 50,000 家商店,每家商店的數據結構相似。如果為每個商店建立獨立 Schema,管理將變得非常困難,因此選擇 共享 Table 並透過
store_id
來區分數據是更好的方式。
綜合比較
Schema 隔離適用於 中型 SaaS 企業,能夠在 數據隔離 與 共享資料庫資源 之間取得良好的平衡。
適用情境 | 不適用情境 |
---|---|
中型 SaaS(租戶數小於 1000 家) | 超大規模 SaaS(租戶數 > 10,000) |
需要數據隔離,但又想共享資料庫資源 | Schema 數量過多,影響效能與管理 |
租戶數據結構可能不同 | 所有租戶數據結構一致,不需要自訂 |
企業對數據安全要求高 | 企業願意透過 tenant_id 來分隔數據 |
✅ 建議的架構選擇
- 小型 SaaS(10~100 租戶) → Schema 隔離 或 獨立資料庫
- 中型 SaaS(100~1000 租戶) → Schema 隔離
- 大型 SaaS(1000~10,000 租戶) → 共享 Table +
tenant_id
- 超大型 SaaS(10,000+ 租戶) → 共享 Table +
tenant_id
或 獨立 Database(僅給 VIP 客戶)
透過這樣的選擇,企業可以在「數據隔離、安全性、效能」之間找到最佳平衡,讓 SaaS 平台更容易管理與擴展 🚀
結論
companyA.employees
這種寫法代表「Schema + Table」,在 PostgreSQL、SQL Server 等支援 Schema 的資料庫中很常見。- Schema 是一種有效的數據隔離方式,能確保不同租戶的數據不會互相影響。
- 對於中型 SaaS 企業來說,「共享資料庫,獨立 Schema」是一種平衡方案,能兼顧數據隔離與資源共享。
這樣的設計有助於 提升數據安全性,同時確保 SaaS 平台能夠靈活擴展! 🚀