本文 AI 產出,尚未審核

MySQL 使用者與權限管理 – CREATE USER / DROP USER


簡介

在 MySQL 中,使用者(user)是資料庫存取的最小單位。只有正確建立、管理使用者,才能確保資料庫的安全性與可維護性。
CREATE USERDROP USER 是兩個最基礎、最常使用的指令,它們負責
新增
移除資料庫帳號。即使你只需要執行簡單的查詢或是開發測試環境,妥善管理使用者仍是不可或缺的步驟。

本篇文章將從概念說明、實作範例、常見陷阱與最佳實踐,帶你一步步掌握 MySQL 使用者的建立與刪除,並提供實務應用情境,讓你能在真實專案中安全、有效地操作 MySQL 使用者。


核心概念

1. 為什麼不直接使用 GRANT 建立使用者?

在 MySQL 5.7 之後,GRANT 仍可同時建立使用者,但官方已建議改用 CREATE USER + GRANT 的兩段式流程,主要原因有:

目的 GRANT 直接建立使用者 CREATE USER + GRANT
清晰度 一行指令即完成,易混淆「建立」與「授權」的邏輯 分開兩步,讓「建立帳號」與「授權」概念更分明
安全性 若忘記加上 IDENTIFIED BY,可能產生空密碼帳號 CREATE USER 必須明確指定密碼或認證方式
兼容性 某些 MySQL 版本的 GRANT 行為略有差異 CREATE USER 為標準化指令,跨版本行為一致

建議:在正式環境或自動化腳本中,始終使用 CREATE USER 先建立帳號,再使用 GRANT 授權。


2. CREATE USER 的基本語法

CREATE USER '使用者名稱'@'主機' IDENTIFIED BY '密碼';
  • '使用者名稱':MySQL 帳號,大小寫視 lower_case_table_names 設定而定。
  • '主機':允許從哪個主機連線。常見的寫法:
    • 'localhost':只能從本機連線。
    • '%':允許任意 IP(不建議在正式環境使用)。
    • '192.168.1.%':只允許特定網段。
  • IDENTIFIED BY:指定明文密碼,MySQL 會自動以雜湊方式儲存。
  • IF NOT EXISTS:可避免重複建立時拋出錯誤。

3. DROP USER 的基本語法

DROP USER '使用者名稱'@'主機';
  • 同樣支援 IF EXISTS,避免因使用者不存在而產生錯誤。
  • 刪除使用者時,所有與之關聯的權限(GRANT)會同時被移除。

4. 認證方式的變化

從 MySQL 8.0 起,預設的認證插件改為 caching_sha2_password,若舊版客戶端不支援,可能需要改用 mysql_native_password

CREATE USER 'old_client'@'%' IDENTIFIED WITH mysql_native_password BY 'MyPass123!';

程式碼範例

以下示範在 MySQL 8.0 環境下,從最簡單的建立使用者到較進階的情境設定。所有範例均已加入 註解,方便理解每一步的目的。

範例 1:建立本機測試帳號

-- 建立一個只能在本機使用的測試帳號 test_user,密碼為 TestPass123
CREATE USER IF NOT EXISTS 'test_user'@'localhost' IDENTIFIED BY 'TestPass123';

說明:使用 IF NOT EXISTS 可避免重複執行腳本時產生錯誤。


範例 2:建立允許特定 IP 段的遠端帳號

-- 允許 192.168.10.* 網段的開發者使用 dev_user,密碼使用較長的隨機字串
CREATE USER 'dev_user'@'192.168.10.%' IDENTIFIED BY 'a9$K8mLz!Qp2#xV7';

技巧:使用 % 通配符限制 IP 範圍,比直接使用 '%' 更安全。


範例 3:使用 caching_sha2_password(MySQL 8.0 預設)

-- 明確指定使用 caching_sha2_password 插件,適合新版客戶端
CREATE USER 'new_user'@'%' IDENTIFIED WITH caching_sha2_password BY 'Strong!Pass2025';

範例 4:兼容舊版客戶端的 mysql_native_password

-- 若應用程式仍使用舊版 MySQL Connector,必須改為 mysql_native_password
CREATE USER 'legacy_app'@'10.0.0.%' IDENTIFIED WITH mysql_native_password BY 'Legacy#2024';

範例 5:刪除使用者(帶 IF EXISTS)

-- 移除不再需要的臨時帳號 temp_user
DROP USER IF EXISTS 'temp_user'@'localhost';

範例 6:一次建立多個使用者

-- 同時建立兩個帳號,分別對應不同主機
CREATE USER 
    'report_user'@'10.1.2.3' IDENTIFIED BY 'Rpt#2025!',
    'audit_user'@'10.1.2.%' IDENTIFIED BY 'Aud!t2025$';

注意:一次建立多個使用者可減少重複的 CREATE USER 語句,提升腳本可讀性。


常見陷阱與最佳實踐

陷阱 可能的後果 解決方案或最佳實踐
使用 '%' 作為主機 任意 IP 均可嘗試連線,增加被暴力破解的風險。 限制 IP 範圍(如 192.168.1.%)或僅允許 localhost
未加 IF NOT EXISTS 重複執行部署腳本時會因使用者已存在拋出錯誤,導致部署中斷。 在自動化腳本中加入 IF NOT EXISTS(或 IF EXISTS)。
忘記設定密碼 產生空密碼帳號,任何人都能直接登入資料庫。 永遠使用 IDENTIFIED BY 或指定認證插件;避免使用 IDENTIFIED WITH auth_socket 除非明確需求。
使用過於簡單的密碼 容易被字典攻擊。 密碼至少 12 位、包含大小寫、數字與特殊字元,或使用密碼管理工具產生隨機密碼。
刪除使用者前未備份權限 失去授權資訊,未來若需復原會很麻煩。 使用 SHOW GRANTS FOR 'user'@'host'; 先備份授權腳本。
忽略認證插件差異 客戶端連線失敗(尤其在 MySQL 8.0 與舊版驅動混用時)。 明確指定 IDENTIFIED WITH <plugin>,或升級客戶端驅動。
忘記刷新權限 新增/刪除使用者後仍看到舊的權限表現。 MySQL 5.7+ 自動刷新;若使用 FLUSH PRIVILEGES; 亦可確保即時生效。

推薦的安全流程

  1. 規劃使用者命名與主機範圍:統一命名規則(如 app_<module>)與 IP 限制。
  2. 產生強密碼:使用 openssl rand -base64 16 或密碼管理器。
  3. 建立使用者CREATE USER IF NOT EXISTS ...
  4. 授權:使用 GRANTROLE(MySQL 8.0+)分配最小權限。
  5. 測試連線:在開發機或測試環境驗證帳號可正確登入、權限符合預期。
  6. 紀錄變更:將 CREATE USER / DROP USER 以及 GRANT 指令寫入版本控制(Git)或變更管理系統。

實際應用場景

1. 多租戶 SaaS 平台

在 SaaS 系統中,每個客戶(租戶)會擁有自己的資料庫或 schema。為了讓每個租戶只能存取自己的資料,常會:

  • 為每個租戶建立 專屬的 MySQL 使用者(例如 tenant_001_user@%)。
  • 限制該使用者只能在特定 schema 上執行 SELECT/INSERT/UPDATE/DELETE
  • 當租戶取消服務時,使用 DROP USER 立即撤銷存取權,確保資料安全。
CREATE USER 'tenant_001_user'@'%' IDENTIFIED BY 'T1$Secure!';
GRANT SELECT, INSERT, UPDATE, DELETE ON tenant_001_db.* TO 'tenant_001_user'@'%';

2. CI/CD 自動化測試環境

在持續整合(CI)流程中,測試腳本常需要臨時資料庫帳號:

  • 建立臨時使用者:測試開始前 CREATE USER,測試結束後 DROP USER
  • 這樣可以避免測試程式直接使用 root,降低意外破壞正式資料的風險。
-- CI pipeline 前置步驟
CREATE USER 'ci_test_user'@'127.0.0.1' IDENTIFIED BY 'CiPass#2025';
GRANT ALL PRIVILEGES ON test_db.* TO 'ci_test_user'@'127.0.0.1';

3. 運維人員分層管理

大型企業往往有多層級的 DB 管理員:

  • 只讀帳號:僅能查詢資料,供監控工具或報表使用。
  • 開發帳號:可在開發環境執行 DML,但無法變更結構。
  • 管理員帳號:具備 CREATE USERDROP USERGRANT 等高階權限。
CREATE USER 'readonly_report'@'10.0.5.%' IDENTIFIED BY 'RptRead#2025';
GRANT SELECT ON prod_db.* TO 'readonly_report'@'10.0.5.%';

總結

  • CREATE USERDROP USER 是 MySQL 使用者管理的核心指令,分離建立與授權的做法更安全、易維護。
  • 正確指定 使用者名稱、主機、密碼或認證插件,並配合 IF NOT EXISTS / IF EXISTS,可以讓腳本在自動化部署中更具韌性。
  • 常見的陷阱包括過度寬鬆的主機限制、弱密碼、忘記備份授權等,遵守最佳實踐(最小權限、密碼政策、變更紀錄)能大幅降低風險。
  • 在多租戶 SaaS、CI/CD 測試、運維分層等實務情境中,透過精準的使用者與權限管理,不僅提升系統安全,也方便日後的維護與審計。

掌握了 CREATE USER / DROP USER 的使用方式,你就能在 MySQL 中建立一套可控、可審計且安全的使用者管理機制,為資料庫的長期健康奠定堅實基礎。祝你在 MySQL 的旅程中順利前行!