MySQL – 檢視表(View)
主題:CREATE VIEW
簡介
在日常的資料庫開發與維護過程中,我們往往需要 簡化查詢、隱藏敏感欄位,或是 提供固定的報表介面 給前端或其他系統使用。直接把複雜的 SELECT 語句寫在程式碼裡不僅難以維護,還會讓資料庫的安全性與效能受到挑戰。
檢視表(View) 正是為了解決這類問題而設計的虛擬表格。它本身不儲存資料,而是將一段 SELECT 語句的結果以「表」的形式呈現,讓使用者像操作真實表格一樣查詢、授權與管理。
本文將深入說明 CREATE VIEW 的語法與使用方式,從基本概念到實務範例,協助您在 MySQL 中快速上手並避免常見的陷阱。
核心概念
1. 什麼是 View?
- 虛擬表格:View 只是一個保存 SELECT 結果的「快照」定義,實際資料仍存於底層表格。
- 安全性:可以只曝光需要的欄位,隱藏敏感資訊。
- 重用性:將常用的複雜查詢封裝成 View,讓其他開發者或報表工具直接引用。
- 可維護性:若底層資料結構變更,只需要調整 View 的定義,而不必改寫所有使用該查詢的程式碼。
2. 基本語法
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION];
- OR REPLACE:如果同名的 View 已存在,直接取代,避免手動先 DROP。
- ALGORITHM:決定 MySQL 執行 View 時的策略,常用
MERGE(將 View 內部的 SELECT 合併至外層查詢)或TEMPTABLE(先把結果寫入臨時表)。 - DEFINER:指定建立 View 的帳號,影響權限檢查。
- WITH CHECK OPTION:防止使用者透過 View 插入、更新違反 View 條件的資料。
小提醒:在 MySQL 5.7 以上,預設的 ALGORITHM 為
UNDEFINED,系統會自行選擇最適合的執行方式。
3. 常見的 View 類型
| 類型 | 說明 | 範例情境 |
|---|---|---|
| 簡單 View | 只包含單一表格的欄位投影 | 把 employees 表的 id、name、department_id 取出 |
| 多表 Join View | 結合多張表的資料 | 把 orders 與 customers 以 customer_id 連接,產生訂單清單 |
| 聚合 View | 包含 GROUP BY、HAVING 等聚合運算 | 計算每個部門的員工人數與平均薪資 |
| 可寫 View(WITH CHECK OPTION) | 允許 INSERT/UPDATE,且限制只能符合 View 條件的資料 | 只允許在 active_users View 中新增狀態為 active 的使用者 |
程式碼範例
以下示範 5 個實務上常見的 CREATE VIEW 用法,每個範例均附上說明與執行結果的簡要解讀。
範例 1:簡單投影 View
-- 建立一個只顯示員工編號、姓名與部門的 View
CREATE VIEW vw_employee_basic AS
SELECT emp_id, emp_name, dept_id
FROM employees;
說明:
vw_employee_basic只保留必要欄位,適合作為前端顯示或 API 回傳的基礎資料。
範例 2:加入條件的 View(WHERE)
-- 只顯示在職員工的資訊
CREATE VIEW vw_active_employee AS
SELECT emp_id, emp_name, dept_id, hire_date
FROM employees
WHERE status = 'active';
說明:透過
WHERE篩選,使用者在查詢此 View 時自動得到「在職」員工,不需要每次都寫條件。
範例 3:多表 Join View
-- 訂單清單:結合 orders 與 customers,顯示客戶名稱與訂單金額
CREATE VIEW vw_order_summary AS
SELECT o.order_id,
c.customer_name,
o.order_date,
o.total_amount
FROM orders AS o
JOIN customers AS c
ON o.customer_id = c.customer_id;
說明:一次取得訂單與客戶的關聯資訊,適合報表或資料分析使用。
範例 4:聚合與 GROUP BY View
-- 計算每個部門的員工人數與平均薪資
CREATE VIEW vw_dept_stats AS
SELECT dept_id,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id;
說明:此 View 已完成聚合,使用者直接查詢
SELECT * FROM vw_dept_stats;即可得到統計結果。
範例 5:可寫 View + WITH CHECK OPTION
-- 只允許在 active_users View 中插入 status 為 'active' 的使用者
CREATE VIEW vw_active_users
AS SELECT user_id, user_name, email, status
FROM users
WHERE status = 'active'
WITH CHECK OPTION;
說明:若使用
INSERT INTO vw_active_users …,MySQL 會自動檢查status是否為'active',若不符合則拋出錯誤,保證資料一致性。
常見陷阱與最佳實踐
| 陷阱 | 為什麼會發生 | 解決方式 / 最佳實踐 |
|---|---|---|
| View 失效於欄位變更 | 底層表格欄位被刪除或改名,View 仍保留舊的 SELECT 定義,導致查詢錯誤。 | 使用 ALTER VIEW ... 或 DROP & RECREATE,並在部署流程中加入檢查腳本。 |
| 過度使用嵌套 View | 多層 View 會產生不必要的查詢複雜度,導致效能下降。 | 盡量保持單層,必要時直接在程式碼或 stored procedure 中寫聯合查詢。 |
| 忘記設定權限 | 使用者只能看到 View,但若底層表格權限不足,仍會被拒絕。 | 為 View 授予 SELECT 權限,同時確保 DEFINER 為具備底層表權限的帳號。 |
忽略 WITH CHECK OPTION |
允許使用者透過 View INSERT/UPDATE 違背原本的過濾條件,破壞資料一致性。 | 必要時加上 WITH CHECK OPTION,尤其在安全或業務規則嚴格的情境。 |
忘記 OR REPLACE |
修改 View 時忘記先 DROP,造成部署失敗。 | 使用 CREATE OR REPLACE VIEW,讓部署腳本更具冪等性(idempotent)。 |
最佳實踐
- 命名慣例:建議以
vw_為前綴,清楚表明是 View。 - 文件化:在資料字典或 README 中列出每個 View 的目的、欄位說明與建立者。
- 權限最小化:只給需要的使用者 SELECT 權限,避免不必要的 UPDATE/DELETE。
- 測試:在 CI/CD 流程加入對 View 的單元測試,確保底層表結構變更不會破壞 View。
- 效能檢測:使用
EXPLAIN觀察 View 被展開後的執行計畫,必要時加索引或改寫為物化表(Materialized View)方案。
實際應用場景
報表系統
- 企業每日需要產出 銷售彙總、庫存狀況 等報表。將複雜的 JOIN、GROUP BY 包裝成 View,報表工具只要
SELECT * FROM vw_monthly_sales;即可。
- 企業每日需要產出 銷售彙總、庫存狀況 等報表。將複雜的 JOIN、GROUP BY 包裝成 View,報表工具只要
多租戶 SaaS 平台
- 為每個租戶建立
vw_tenant_{id}_orders,只顯示該租戶的訂單資料,避免資料洩漏。
- 為每個租戶建立
資料隱私
- 在 HR 系統中,使用 View 隱藏員工的 薪資、身分證號,只提供
emp_id、name、department給普通使用者。
- 在 HR 系統中,使用 View 隱藏員工的 薪資、身分證號,只提供
API 讀取層
- 後端 API 直接對 View 執行 SELECT,減少程式碼內的硬編碼查詢,提升維護效率。
可寫 View 作為業務規則入口
- 例如只允許在
vw_active_users中新增「啟用」的使用者,把業務規則寫在資料庫層,減少前端或服務端重複驗證的負擔。
- 例如只允許在
總結
- View 是 MySQL 中強大的虛擬表格概念,透過 CREATE VIEW 可以把複雜查詢封裝、提升安全性、加速開發。
- 正確使用 ALGORITHM、DEFINER、WITH CHECK OPTION 等選項,可讓 View 在效能與資料完整性上表現更佳。
- 了解常見陷阱(欄位變更、過度嵌套、權限問題)並遵守 命名慣例、權限最小化、文件化 等最佳實踐,能讓您的資料庫維護成本大幅下降。
- 在實務上,View 常被用於報表、SaaS 多租戶、資料隱私與可寫業務規則等場景,是連接資料庫與應用層的重要橋樑。
透過本文的概念與範例,相信您已具備在 MySQL 中 建立、管理與最佳化 View 的能力。快把學到的技巧應用到自己的專案中,讓資料庫變得更安全、更易維護,也更具彈性吧!