在 MySQL 中,权限管理是数据库安全的核心组成部分。MySQL 提供了一套完整的 数据控制语言(DCL, Data Control Language) 用于用户账户的创建、授权、权限查询、撤销和删除。
这些操作主要通过数据库 mysql 中的权限表(如 user、db、tables_priv 等)进行控制,并可通过 SQL 语句或管理命令实现。

一、权限相关 SQL 分类总览

类别SQL 语句功能
用户管理CREATE USER
ALTER USER
DROP USER
创建、修改、删除用户
权限授予GRANT授予用户或角色权限
权限撤销REVOKE撤销用户或角色权限
权限查询SHOW GRANTS查看用户或角色的权限
角色管理(MySQL 8.0+)CREATE ROLE
DROP ROLE
GRANT role TO user
REVOKE role FROM user
SET DEFAULT ROLE
SET ROLE
角色的创建、分配、激活等
密码与安全策略SET PASSWORD
ALTER USER ... IDENTIFIED BY
修改密码、设置过期策略等

✅ 所有 DCL 语句在执行后自动刷新权限缓存,无需手动 FLUSH PRIVILEGES(除非直接修改 mysql 系统表)。

二、详细语法与说明

1. 用户管理

(1) CREATE USER

创建新用户账户。

CREATE USER 'username'@'host'
IDENTIFIED BY 'password'
[REQUIRE {NONE | SSL | X509 | ...}]
[PASSWORD EXPIRE [DEFAULT | NEVER | INTERVAL N DAY]]
[ACCOUNT LOCK | UNLOCK];

示例:

CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'SecurePass123!';
CREATE USER 'temp'@'localhost' PASSWORD EXPIRE INTERVAL 30 DAY;

(2) ALTER USER

修改现有用户属性(密码、过期策略、锁定状态等)。

ALTER USER 'username'@'host'
IDENTIFIED BY 'new_password'
[PASSWORD EXPIRE | NEVER]
[ACCOUNT LOCK | UNLOCK];

示例:

ALTER USER 'old_user'@'%' IDENTIFIED BY 'NewPass456' PASSWORD EXPIRE;
ALTER USER 'test'@'localhost' ACCOUNT LOCK;

(3) DROP USER

删除用户账户会同时移除该用户的所有权限(包括全局、数据库、表等各级权限),并从 mysql.user 及其他权限表中清除记录。

DROP USER [IF EXISTS] 'username'@'host' [, 'user2'@'host2'] ...;

示例:

-- 删除单个用户
DROP USER 'temp_user'@'localhost';

-- 删除多个用户
DROP USER 'user1'@'%', 'user2'@'192.168.%';

2. 权限授予:GRANT

语法

GRANT privilege_type [(column_list)]
ON [database_name.][table_name]
TO 'username'@'host' [, 'user2'@'host2'] ...
[WITH GRANT OPTION]
[AS role_name];  -- MySQL 8.0+

常见权限类型

权限作用范围说明
ALL [PRIVILEGES]全局/数据库/表所有可用权限(不含 GRANT OPTION)
SELECT, INSERT, UPDATE, DELETE表/列DML 操作
CREATE, DROP, ALTER数据库/表DDL 操作
USAGE全局“无权限”,仅允许连接
GRANT OPTION全局/数据库/表允许将自身权限授予他人
PROCESS, RELOAD, SHUTDOWN全局管理权限(高危!)

示例

-- 授予数据库级读写权限
GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'app_user'@'%';

-- 授予全局只读(监控账号)
GRANT SELECT ON *.* TO 'monitor'@'10.0.0.%';

-- 授予列级权限
GRANT SELECT (id, name), UPDATE (email) ON mydb.users TO 'hr_user'@'localhost';

-- 允许转授权限
GRANT SELECT ON mydb.* TO 'delegate'@'%' WITH GRANT OPTION;

3. 权限撤销:REVOKE

语法

REVOKE privilege_type [(column_list)]
ON [database_name.][table_name]
FROM 'username'@'host' [, ...];

-- 撤销所有权限(包括 GRANT OPTION)
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'host';

-- 撤销数据库级权限
REVOKE INSERT, UPDATE ON mydb.* FROM 'app_user'@'%';

-- 撤销全局权限
REVOKE CREATE USER ON *.* FROM 'admin'@'localhost';

示例

REVOKE UPDATE ON mydb.orders FROM 'app_user'@'%';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'temp_user'@'localhost';

注意:REVOKE 不会删除用户,仅移除权限。

4. 查看权限:SHOW GRANTS

语法

SHOW GRANTS;                          -- 当前用户
SHOW GRANTS FOR 'username'@'host';    -- 指定用户
SHOW GRANTS FOR CURRENT_USER();       -- 显式当前用户

输出示例:

GRANT USAGE ON *.* TO `app_user`@`%`
GRANT SELECT, INSERT ON `mydb`.* TO `app_user`@`%`

✅ 返回的是可直接执行的 GRANT 语句,便于权限迁移或审计。

直接查询权限表

-- 全局权限
SELECT * FROM mysql.user WHERE User = 'username' AND Host = 'host';

-- 数据库级权限
SELECT * FROM mysql.db WHERE User = 'username' AND Host = 'host';

-- 表级权限
SELECT * FROM mysql.tables_priv WHERE User = 'username' AND Host = 'host';

5. 角色管理(MySQL 8.0+)

角色是一组权限的集合,可简化权限分配。

(1) 创建/删除角色

CREATE ROLE 'role_name';
DROP ROLE 'role_name';

(2) 授予角色权限

GRANT SELECT, INSERT ON mydb.* TO 'data_reader';

(3) 将角色授予用户

GRANT 'data_reader' TO 'app_user'@'%';

(4) 激活角色

-- 默认不激活,需设置默认角色
SET DEFAULT ROLE 'data_reader' TO 'app_user'@'%';

-- 或会话中临时激活
SET ROLE 'data_reader';
SET ROLE ALL;        -- 激活所有授予的角色
SET ROLE NONE;       -- 停用所有角色

(5) 查看角色权限

SHOW GRANTS FOR 'app_user'@'%';          -- 显示角色分配
SHOW GRANTS FOR 'app_user'@'%' USING 'data_reader'; -- 显示角色展开后的权限

6. 密码管理

(1) 修改密码(多种方式)

-- 方式1:SET PASSWORD(推荐)
SET PASSWORD FOR 'user'@'host' = 'new_password';

-- 方式2:ALTER USER(更灵活)
ALTER USER 'user'@'host' IDENTIFIED BY 'new_password';

-- 方式3:旧版(不推荐)
SET PASSWORD = PASSWORD('new_password'); -- 仅当前用户,且明文风险

(2) 强制密码过期

ALTER USER 'user'@'host' PASSWORD EXPIRE;

7. 查看用户

(1) 查看所有用户

SELECT User, Host FROM mysql.user;

⚠️ 注意:执行此语句需要具有 SELECT 权限访问 mysql.user 表(通常为管理员权限)

(2) 查看当前登录用户

SELECT USER(), CURRENT_USER();
  • USER():客户端尝试连接时使用的用户名和主机。
  • CURRENT_USER():实际被认证的账户(用于权限判断)。

三、权限层级与作用范围

层级语法形式存储表
全局ON *.*mysql.user
数据库ON db_name.*mysql.db
表ON db_name.tbl_namemysql.tables_priv
列ON db_name.tbl_name (col1, col2)mysql.columns_priv
存储过程/函数ON PROCEDURE db_name.proc_namemysql.procs_priv

权限检查顺序:全局 → 数据库 → 表 → 列(取最具体的匹配)。

四、常用权限审计与清理命令汇总

-- 1. 列出所有用户
SELECT User, Host FROM mysql.user;

-- 2. 查看某用户权限
SHOW GRANTS FOR 'user'@'host';

-- 3. 查找空密码用户
SELECT User, Host FROM mysql.user WHERE authentication_string = '';

-- 4. 查找通配符主机高权限用户
SELECT User, Host FROM mysql.user 
WHERE Host = '%' AND (Insert_priv = 'Y' OR Super_priv = 'Y');

-- 5. 撤销所有权限并删除用户
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'host';
DROP USER 'user'@'host';

-- 6. 刷新权限(仅在直接修改 mysql 表时需要)
FLUSH PRIVILEGES;

五、重要注意事项

  1. 权限由 (User, Host) 唯一确定
    'admin'@'localhost' ≠ 'admin'@'%'。

  2. GRANT 自动创建用户(若不存在)

    GRANT SELECT ON *.* TO 'newuser'@'%' IDENTIFIED BY 'pass'; -- 不推荐!
    

    ⚠️ 此行为在 MySQL 8.0 中已被弃用,建议先 CREATE USER 再 GRANT。

  3. USAGE 权限 = 无权限,仅允许连接
    常用于限制用户只能登录但不能操作数据。

  4. 不要直接修改 mysql 系统表
    应使用 DCL 语句,否则需手动 FLUSH PRIVILEGES。

  5. 权限变更对新连接生效
    已存在的连接仍保留旧权限,直到重连。

六、权限生效机制

  • MySQL 在启动时或执行 FLUSH PRIVILEGES 时加载权限表到内存。
  • 使用 GRANT、REVOKE、CREATE USER、DROP USER 等语句会自动更新内存中的权限缓存,无需手动刷新。
  • 直接修改 mysql 库中的表(如 UPDATE mysql.user)不会立即生效,必须执行 FLUSH PRIVILEGES;。

七、总结:权限管理最佳实践

  • 先 CREATE USER,再 GRANT;
  • 使用最小权限原则;
  • 避免 'user'@'%',限制具体 IP 或子网;
  • 定期审计:SHOW GRANTS + 连接日志分析;
  • MySQL 8.0+ 优先使用 角色(Role) 管理复杂权限;
  • 敏感操作记录到审计日志。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐