MySQL 權限儲存於 mysql 系統資料庫的五張表,形成「全域 → 資料庫 → 資料表 → 欄位」四層遞進檢查機制:
| 層級 | 權限表 | 生效範圍 | 典型用途 |
|---|---|---|---|
| 1. 全域 | user | 整個伺服器所有資料庫 | 超級管理員、備份帳號、監控帳號 |
| 2. 資料庫 | db | 特定資料庫內所有物件 | 應用帳號、開發帳號 |
| 3. 資料表 | tables_priv | 特定資料庫的特定資料表 | 敏感表限制、跨庫只讀 |
| 4. 欄位 | columns_priv | 特定表的特定欄位 | 薪資、身分證等敏感欄位 |
| 5. 主機 | host | 輔助 db 表,舊版本相容 | 極少直接使用 |
Host:允許連線的主機(%、localhost、IP、主機名)User:使用者名稱authentication_string / Password:加密密碼(PASSWORD() 或 caching_sha2_password)Select_priv、Insert_priv...Grant_priv:全域權限旗標 (Y/N)user 表權限全設 N,僅允許登入PASSWORD() 或 SET PASSWORD,不可存明文localhost,禁止 %admin@localhost),密碼離線保管,防 root 遺忘-- MySQL 5.7+ CREATE USER 'bill'@'%' IDENTIFIED BY '12345'; -- 或 8.0+ CREATE USER 'bill'@'%' IDENTIFIED WITH caching_sha2_password BY '12345'; -- 授權走 GRANT,不直接改 user 表 GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'bill'@'%';
查詢時:先檢查 user 表全域權限 → 再檢查 db 表資料庫權限 → 最後檢查 tables_priv。
-- 授予 mydb 所有權限(含 GRANT OPTION) GRANT ALL PRIVILEGES ON mydb.* TO 'bill'@'%'; -- 僅授予讀寫 GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'bill'@'%'; -- 回收權限 REVOKE INSERT, UPDATE ON mydb.* FROM 'bill'@'%'; -- 查看權限 SHOW GRANTS FOR 'bill'@'%';
GRANT 立即生效,無需 FLUSH PRIVILEGESGRANT OPTION 者只能授予自己擁有的權限User、Db、Table_name:三元組定位Table_priv:SET 型別,含 Select, Insert, Update, Delete, Alter, Create, Drop, Grant, Index, ReferencesColumn_name,Column_priv 為 Select, Insert, Update, References-- 僅允許讀取 employees 表的 name、dept 欄位 GRANT SELECT (name, dept) ON hr.employees TO 'report_user'@'%';
'bill'@'10.0.1.%' vs 'bill'@'%'GRANT SELECT, INSERT ON mydb.* TO 'app'@'10.0.%'; GRANT SELECT ON mydb.* TO 'app'@'%';
FLUSH PRIVILEGES;
直接 INSERT/UPDATE/DELETE 系統表必須執行此命令;使用 GRANT/REVOKE/CREATE USER 則自動生效。
''@'localhost'、''@'%',必須 DROP USER ''@'%';test 資料庫預設所有人可寫:DROP DATABASE test; 或收回 db 表權限ALTER USER 'app'@'%' PASSWORD EXPIRE NEVER;caching_sha2_password,舊驅動需改 mysql_native_password-- 列出所有帳號權限
SELECT User, Host,
CONCAT_WS(', ',
IF(Select_priv='Y','SELECT',''),
IF(Insert_priv='Y','INSERT',''),
IF(Grant_priv='Y','GRANT','')
) AS global_privs
FROM mysql.user
WHERE User != '';