資料庫層級結構:Database、Schema、Table 的關係與應用

更新日期: 2025 年 3 月 20 日

本文為 SaaS 架構基礎,第 3 篇:

  1. 網站入門指南:認識站點(Site)的概念與應用
  2. 網站前台與後台:初學者指南
  3. 資料庫層級結構:Database、Schema、Table 的關係與應用 👈進度
  4. 多租戶 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(綱要)

SchemaDatabase 內的邏輯分區(Logical Partition),負責 組織與隔離數據,讓數據管理更加有條理。

在一些支援 Schema 的資料庫系統(如 PostgreSQL、SQL Server)中,每個 Schema 相當於一個獨立的命名空間(Namespace),它可以包含多張 Table、索引、視圖(Views)等物件。

這讓我們能夠有效地將數據進行分類管理,例如:

  • 在多租戶架構(Multi-Tenant Architecture)下,每個租戶的數據可以存放在獨立的 Schema 內,例如 companyAcompanyB
  • 在大型企業系統中,可以透過 Schema 區分不同業務領域的數據,例如 HR(人資)Sales(銷售)Finance(財務)

📌 Schema 的優勢

數據隔離:確保不同企業或業務的數據不會互相影響。
權限管理:可以針對不同的 Schema 設定不同的存取權限,提高數據安全性。
避免命名衝突:不同 Schema 內可以擁有相同名稱的 Table,例如 companyA.employeescompanyB.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_DBDatabase(資料庫),存放所有企業的數據。
  • companyAcompanyBSchema(綱要),確保不同企業的數據邏輯隔離。
  • employeespayrollattendanceTable(資料表),存放具體的員工資訊、薪資數據和考勤記錄。

📌 查詢某家企業的員工數據 假設我們要查詢 公司 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)

idnamepositionsalary
1AliceManager80000
2BobEngineer70000

🔹 公司 B 的員工表 (companyB.employees)

idnamepositionsalary
1CharlieHR60000
2DavidSales65000

使用 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 進行備份與維護,運營成本大幅提高。

📌 替代方案
對於 超大規模租戶數量(幾萬家以上),建議考慮:

  1. 共享 Table + tenant_id(適用於數據結構統一的情境)。
  2. 獨立 Database(適用於大型租戶,確保數據完全隔離)。

📌 範例

  • 某電商平台擁有 50,000 家商店,每家商店的數據結構相似。如果為每個商店建立獨立 Schema,管理將變得非常困難,因此選擇 共享 Table 並透過 store_id 來區分數據是更好的方式。

綜合比較

Schema 隔離適用於 中型 SaaS 企業,能夠在 數據隔離共享資料庫資源 之間取得良好的平衡。

適用情境不適用情境
中型 SaaS(租戶數小於 1000 家)超大規模 SaaS(租戶數 > 10,000)
需要數據隔離,但又想共享資料庫資源Schema 數量過多,影響效能與管理
租戶數據結構可能不同所有租戶數據結構一致,不需要自訂
企業對數據安全要求高企業願意透過 tenant_id 來分隔數據

✅ 建議的架構選擇

  1. 小型 SaaS(10~100 租戶)Schema 隔離 或 獨立資料庫
  2. 中型 SaaS(100~1000 租戶)Schema 隔離
  3. 大型 SaaS(1000~10,000 租戶)共享 Table + tenant_id
  4. 超大型 SaaS(10,000+ 租戶)共享 Table + tenant_id 或 獨立 Database(僅給 VIP 客戶)

透過這樣的選擇,企業可以在「數據隔離、安全性、效能」之間找到最佳平衡,讓 SaaS 平台更容易管理與擴展 🚀


結論

  • companyA.employees 這種寫法代表「Schema + Table」,在 PostgreSQL、SQL Server 等支援 Schema 的資料庫中很常見。
  • Schema 是一種有效的數據隔離方式,能確保不同租戶的數據不會互相影響。
  • 對於中型 SaaS 企業來說,「共享資料庫,獨立 Schema」是一種平衡方案,能兼顧數據隔離與資源共享。

這樣的設計有助於 提升數據安全性,同時確保 SaaS 平台能夠靈活擴展! 🚀

Similar Posts