[小技巧19]MySQL 权限管理全指南:用户、角色、授权与安全实践

在 MySQL 中,权限管理是数据库安全的核心组成部分。MySQL 提供了一套完整的 数据控制语言(DCL, Data Control Language) 用于用户账户的创建、授权、权限查询、撤销和删除。

这些操作主要通过数据库 mysql 中的权限表(如 userdbtables_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

创建新用户账户。

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

示例:

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

(2) ALTER USER

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

sql 复制代码
ALTER USER 'username'@'host'
IDENTIFIED BY 'new_password'
[PASSWORD EXPIRE | NEVER]
[ACCOUNT LOCK | UNLOCK];

示例:

sql 复制代码
ALTER USER 'old_user'@'%' IDENTIFIED BY 'NewPass456' PASSWORD EXPIRE;
ALTER USER 'test'@'localhost' ACCOUNT LOCK;

(3) DROP USER

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

sql 复制代码
DROP USER [IF EXISTS] 'username'@'host' [, 'user2'@'host2'] ...;

示例:

sql 复制代码
-- 删除单个用户
DROP USER 'temp_user'@'localhost';

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

2. 权限授予:GRANT

语法

sql 复制代码
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 全局 管理权限(高危!)

示例

sql 复制代码
-- 授予数据库级读写权限
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

语法

sql 复制代码
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';

示例

sql 复制代码
REVOKE UPDATE ON mydb.orders FROM 'app_user'@'%';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'temp_user'@'localhost';

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

4. 查看权限:SHOW GRANTS

语法

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

输出示例:

sql 复制代码
GRANT USAGE ON *.* TO `app_user`@`%`
GRANT SELECT, INSERT ON `mydb`.* TO `app_user`@`%`

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

直接查询权限表

sql 复制代码
-- 全局权限
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) 创建/删除角色

sql 复制代码
CREATE ROLE 'role_name';
DROP ROLE 'role_name';

(2) 授予角色权限

sql 复制代码
GRANT SELECT, INSERT ON mydb.* TO 'data_reader';

(3) 将角色授予用户

sql 复制代码
GRANT 'data_reader' TO 'app_user'@'%';

(4) 激活角色

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

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

(5) 查看角色权限

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

6. 密码管理

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

sql 复制代码
-- 方式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) 强制密码过期

sql 复制代码
ALTER USER 'user'@'host' PASSWORD EXPIRE;

7. 查看用户

(1) 查看所有用户

sql 复制代码
SELECT User, Host FROM mysql.user;

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

(2) 查看当前登录用户

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

三、权限层级与作用范围

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

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

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

sql 复制代码
-- 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 自动创建用户(若不存在)

    sql 复制代码
    GRANT SELECT ON *.* TO 'newuser'@'%' IDENTIFIED BY 'pass'; -- 不推荐!

    ⚠️ 此行为在 MySQL 8.0 中已被弃用 ,建议先 CREATE USERGRANT

  3. USAGE 权限 = 无权限,仅允许连接

    常用于限制用户只能登录但不能操作数据。

  4. 不要直接修改 mysql 系统表

    应使用 DCL 语句,否则需手动 FLUSH PRIVILEGES

  5. 权限变更对新连接生效

    已存在的连接仍保留旧权限,直到重连。

六、权限生效机制

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

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

  • CREATE USER,再 GRANT
  • 使用最小权限原则;
  • 避免 'user'@'%',限制具体 IP 或子网;
  • 定期审计:SHOW GRANTS + 连接日志分析;
  • MySQL 8.0+ 优先使用 角色(Role) 管理复杂权限;
  • 敏感操作记录到审计日志。
相关推荐
heartbeat..15 小时前
Spring AOP 全面详解(通俗易懂 + 核心知识点 + 完整案例)
java·数据库·spring·aop
麦聪聊数据17 小时前
MySQL并发与锁:从“防止超卖”到排查“死锁”
数据库·sql·mysql
tianyuanwo17 小时前
合并XFS分区:将独立分区安全融入LVM的完整指南
安全·lvm
智驱力人工智能18 小时前
守护流动的规则 基于视觉分析的穿越导流线区检测技术工程实践 交通路口导流区穿越实时预警技术 智慧交通部署指南
人工智能·opencv·安全·目标检测·计算机视觉·cnn·边缘计算
AC赳赳老秦18 小时前
DeepSeek 私有化部署避坑指南:敏感数据本地化处理与合规性检测详解
大数据·开发语言·数据库·人工智能·自动化·php·deepseek
myzshare19 小时前
实战分享:我是如何用SSM框架开发出一个完整项目的
java·mysql·spring cloud·微信小程序
YMatrix 官方技术社区19 小时前
YMatrix 存储引擎解密:MARS3 存储引擎如何超越传统行存、列存实现“时序+分析“场景性能大幅提升?
开发语言·数据库·时序数据库·数据库架构·智慧工厂·存储引擎·ymatrix
2501_9458374319 小时前
云服务器的防护体系构建之道
网络·安全
辞砚技术录20 小时前
MySQL面试题——索引2nd
数据库·mysql·面试