GRANT 基礎語法
GRANT privilege_type [, privilege_type] ...
ON [object_type] priv_level
TO user_specification [, user_specification] ...
[REQUIRE {NONE | ssl_option ...}]
[WITH with_option ...]
user_specification:
user [IDENTIFIED BY 'password']
[PASSWORD EXPIRE | PASSWORD EXPIRE NEVER | PASSWORD EXPIRE INTERVAL N DAY]
with_option:
GRANT OPTION
| MAX_QUERIES_PER_HOUR count
| MAX_UPDATES_PER_HOUR count
| MAX_CONNECTIONS_PER_HOUR count
| MAX_USER_CONNECTIONS count
四大典型角色授權範本
1. 普通資料用戶(CRUD)
GRANT SELECT, INSERT, UPDATE, DELETE ON testdb.* TO 'common_user'@'%' IDENTIFIED BY 'pass123';
2. 開發人員(DDL + 程式碼物件)
GRANT CREATE, ALTER, DROP, INDEX, REFERENCES,
CREATE TEMPORARY TABLES,
CREATE VIEW, SHOW VIEW,
CREATE ROUTINE, ALTER ROUTINE, EXECUTE
ON testdb.* TO 'developer'@'192.168.0.%' IDENTIFIED BY 'dev_pass';
3. 單庫 DBA
GRANT ALL PRIVILEGES ON testdb.* TO 'dba'@'localhost' IDENTIFIED BY 'dba_pass';
4. 超級 DBA(全域)
GRANT ALL ON *.* TO 'root'@'localhost' IDENTIFIED BY 'root_pass' WITH GRANT OPTION;
五大權限作用層級詳解
| 層級 | 語法範例 | 影響範圍 | 典型用途 |
| 全域 | GRANT SELECT ON *.* TO 'u'@'%'; | 所有資料庫、所有表 | 超級管理員、監控帳號 |
| 資料庫 | GRANT SELECT ON testdb.* TO 'u'@'%'; | 單一資料庫所有表 | 應用帳號、單庫 DBA |
| 資料表 | GRANT SELECT, INSERT ON testdb.orders TO 'u'@'%'; | 單一表 | 微服務資料隔離、敏感表限制 |
| 欄位 | GRANT SELECT (id, name, email) ON testdb.users TO 'u'@'%'; | 單一表指定欄位 | GDPR/隱私保護、最小權限原則 |
| 程序/函數 | GRANT EXECUTE ON PROCEDURE testdb.proc TO 'u'@'%'; | 單一存儲程序/函數 | 封裝業務邏輯、防止直接操作表 |
查看與撤銷權限
-- 查看當前用戶權限
SHOW GRANTS;
-- 查看指定用戶權限
SHOW GRANTS FOR 'dba'@'localhost';
-- 撤銷權限(語法與 GRANT 類似,TO 換 FROM)
REVOKE ALL ON *.* FROM 'dba'@'localhost';
REVOKE SELECT ON testdb.orders FROM 'u'@'%';
關鍵注意事項(避坑指南)
- 生效需重連:
GRANT/REVOKE 後,用戶必須重新連線才生效。
- WITH GRANT OPTION 慎用:允許受權用戶再授權他人,易失控。生產環境建議僅 DBA 持有,統一管理。
proc 表權限陷阱:呼叫存儲程序需 mysql.proc 表 SELECT 權限,單授業務庫不夠。
GRANT SELECT ON mysql.proc TO 'app'@'%';
- 五大授權表結構:
user:全域權限、連線驗證
db:資料庫級權限
host:主機級細粒度控制(不受 GRANT/REVOKE 影響,罕用)
tables_priv:表級權限
columns_priv:欄位級權限
- MySQL 8.0+ 推薦用
CREATE USER + GRANT 分離,不再支援 GRANT ... IDENTIFIED BY 隱建用戶。
實戰授權腳本範本
#!/bin/bash
# grant_template.sh
DB="prod_db"
APP_USER="app_user"
APP_PASS="StrongPass2024!"
APP_HOST="10.0.%"
mysql -uroot -p -e "
CREATE USER IF NOT EXISTS '${APP_USER}'@'${APP_HOST}' IDENTIFIED BY '${APP_PASS}';
GRANT SELECT, INSERT, UPDATE, DELETE ON \`${DB}\`.* TO '${APP_USER}'@'${APP_HOST}';
GRANT EXECUTE ON \`${DB}\`.* TO '${APP_USER}'@'${APP_HOST}';
FLUSH PRIVILEGES;
"