本文 AI 產出,尚未審核

MySQL 使用者與權限管理:GRANT / REVOKE 完全攻略

簡介

在企業級的資料庫環境中,安全性可維護性往往是系統能否穩定運作的關鍵。MySQL 透過 使用者(User)與 權限(Privilege)機制,讓管理者可以細緻地控制誰能對哪個資料庫、哪張資料表、甚至是哪條 SQL 語句執行操作。
本篇文章聚焦在兩個最常使用的指令——GRANTREVOKE,說明它們的語法、使用情境與最佳實務,幫助你從入門到中階的權限管理需求,都能得心應手。

核心概念

1. 權限的基本類型

MySQL 的權限大致可分為 全域資料庫資料表欄位例程(PROCEDURE/FUNCTION) 五層。

  • 全域權限ON *.*)會影響所有資料庫與資料表,常見於 SUPERFILE 等高階權限。
  • 資料庫層級ON db_name.*)只授予指定資料庫內的所有物件。
  • 資料表層級ON db_name.tbl_name)針對單一資料表。
  • 欄位層級ON db_name.tbl_name (col1, col2))允許細部控制欄位的讀寫。

2. GRANT 的語法結構

GRANT priv_type [(column_list)] [, priv_type ...]
ON object_type
TO user_specification [, user_specification ...]
[WITH GRANT OPTION];
  • priv_type:欲授予的權限,如 SELECTINSERTUPDATEDELETEEXECUTE 等。
  • object_type:權限的作用範圍,例如 *.*(全域)或 mydb.*(資料庫)等。
  • user_specification:使用者與主機的組合,格式為 'user'@'host'
  • WITH GRANT OPTION:允許被授權者再把同樣的權限授予其他使用者。

3. REVOKE 的語法結構

REVOKE priv_type [(column_list)] [, priv_type ...]
ON object_type
FROM user_specification [, user_specification ...];

REVOKE 會從指定使用者移除先前的權限,若同時撤銷 GRANT OPTION,則會限制其再授權的能力。

4. 權限變更的即時生效與刷新

MySQL 在執行 GRANT / REVOKE 後,會自動更新內部的權限快取(mysql.usermysql.db 等表格),不需要手動執行 FLUSH PRIVILEGES。只有在直接修改權限表格時才需要 FLUSH PRIVILEGES

程式碼範例

以下範例均以 root(或具備 GRANT OPTION 的管理者)身份執行,示範常見的授權與撤權情境。

範例 1:建立新使用者並授予全域讀寫權限

-- 建立使用者 alice,密碼使用 MySQL 8.0 內建的認證方式
CREATE USER 'alice'@'%' IDENTIFIED BY 'StrongP@ssw0rd';

-- 授予全域 SELECT、INSERT、UPDATE、DELETE 權限
GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'alice'@'%';

說明% 表示任意主機都可連線,實務上建議限制為公司內部的 IP 範圍,例如 'alice'@'192.168.10.%'

範例 2:僅授予特定資料庫的 SELECT 權限,並允許再授權

GRANT SELECT ON sales_db.* TO 'alice'@'%' WITH GRANT OPTION;

說明WITH GRANT OPTIONalice 可以把 SELECT 權限再授給其他使用者,常用於資料分析團隊的「只讀」帳號。

範例 3:欄位層級的授權(只允許讀取 email 欄位)

GRANT SELECT (email) ON hr_db.employees TO 'bob'@'localhost';

說明:此設定僅允許 bob 讀取 employees 表的 email 欄位,其他欄位會回傳 NULL

範例 4:撤銷特定資料表的 UPDATE 權限

REVOKE UPDATE ON inventory.products FROM 'alice'@'%';

說明:即使 alice 之前擁有全域的 UPDATE 權限,這條指令會在 inventory.products 表上移除它,使其只能執行 SELECTINSERTDELETE

範例 5:同時撤銷 GRANT OPTION 與所有權限

REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'alice'@'%';
DROP USER IF EXISTS 'alice'@'%';

說明:先撤銷所有權限與授權能力,再刪除使用者帳號,確保不留下任何隱藏的權限。

常見陷阱與最佳實踐

陷阱 可能的後果 改善方式
使用 GRANT ALL 在全域 任何人都有最高權限,易成為資安漏洞。 僅授予必要的最小權限(最小權限原則)。
忘記加上主機限定 ('user'@'%') 帳號可被任意 IP 暴力嘗試。 盡量使用具體的 IP 或子網 ('user'@'10.0.0.%')。
mysql.* 表直接編輯後未 FLUSH 權限變更不會立即生效,造成測試困擾。 只使用 GRANT/REVOKE,或在手動編輯後執行 FLUSH PRIVILEGES
撤銷權限時忘記 FROM 語法錯誤,導致指令執行失敗。 確認使用 REVOKE ... FROM 的正確語法。
授權過度使用 WITH GRANT OPTION 使用者自行擴散權限,增加管理成本。 僅在確實需要的情境下使用,並定期審核授權鏈。

最佳實踐

  1. 最小權限:先從最小的權限開始,逐步測試功能需求,再適度放寬。
  2. 角色(Role)概念:MySQL 8.0 以上支援角色(CREATE ROLE),可將一組權限抽象成角色,再授予使用者,方便管理。
  3. 定期審計:使用 SELECT * FROM mysql.user;mysql.db; 等表格,或透過 mysqlshow --privileges 檢查權限分布。
  4. 密碼政策:配合 validate_password 插件,強制使用者密碼符合複雜度要求。
  5. 日誌與監控:開啟 audit_log(或使用 MariaDB 的 MariaDB Audit Plugin),即時偵測不尋常的授權變更。

實際應用場景

  1. 開發/測試環境的臨時帳號

    • 使用 GRANT SELECT, INSERT, UPDATE, DELETE ON dev_db.* TO 'dev_user'@'10.0.1.%',並在測試結束後 DROP USER 'dev_user'@'10.0.1.%';,防止帳號遺留。
  2. 資料分析平台的只讀帳號

    • 為 BI 團隊建立 analytics 角色:
      CREATE ROLE 'analytics';
      GRANT SELECT ON analytics_db.* TO 'analytics';
      GRANT 'analytics' TO 'charlie'@'10.0.2.%';
      
    • 只要撤銷角色,即可一次收回所有只讀權限。
  3. 多租戶 SaaS 系統的資料隔離

    • 為每個客戶建立獨立的資料庫與使用者:
      CREATE DATABASE tenant_001;
      CREATE USER 'tenant001_user'@'%' IDENTIFIED BY 'Pwd123!';
      GRANT ALL PRIVILEGES ON tenant_001.* TO 'tenant001_user'@'%';
      
    • 透過 REVOKE ALL PRIVILEGES FROM 'tenant001_user'@'%'; DROP USER ...; 快速關閉帳號。
  4. 自動化部署腳本

    • 在 CI/CD pipeline 中加入授權腳本(使用 mysql -e "GRANT ..."),確保每次部署後環境權限保持一致。

總結

GRANTREVOKE 是 MySQL 權限管理的核心工具,掌握其語法與層級概念,能讓你在 安全可維護彈性 之間取得最佳平衡。本文從概念說明、實作範例、常見陷阱到實務場景,提供了一條完整的學習路徑;配合 最小權限原則、角色化管理與定期審計,你的 MySQL 環境將更加堅固、易於運營。祝你在資料庫管理的道路上,越走越順!