
权限管理到底管什么?不是“能连上”,而是“能干啥”
权限管理就是控制谁能在什么范围内对数据库执行哪些操作。它不决定用户能不能登录(那是认证的事),而是登录之后:能不能查 orders 表、能不能删 users 记录、能不能建新库、甚至能不能重启服务。MySQL 把权限分层设计——全局(.*)、库级(myapp.*)、表级(myapp.orders)、列级(myapp.users.email),粒度越细,风险越可控。
用户和角色不是“同一种东西”,别混着创建
用户是真实可登录的账号,比如 'alice'@'192.168.1.%';角色是纯权限容器,不能登录,比如 'dev_team'。这是关键区别:角色不带密码、不参与认证流程,只用来打包权限。MySQL 8.0+ 才支持角色,5.7 及更早版本压根没有 CREATE ROLE 这个语法,强行执行会报错 ERROR 1064 (42000)。
- 创建用户用
CREATE USER,必须指定主机名('%'或'localhost') - 创建角色用
CREATE ROLE,名字加单引号,如'app_readonly' - 一个用户可以被授予多个角色,一个角色也可以分配给多个用户——是多对多关系
权限不会自动生效:角色必须“激活”或设为默认
给用户 GRANT 'dev_team' TO 'alice'@'192.168.1.%' 只是把角色挂上去,alice 登录后默认还是“裸权限”状态。她得显式执行 SET ROLE 'dev_team' 才能用上那些 SELECT/INSERT 权限。否则 SELECT * FROM myapp.orders 会直接报 ERROR 1044 (42000): Access denied。
- 想省事?用
ALTER USER 'alice'@'192.168.1.%' DEFAULT ROLE 'dev_team'设为默认角色 - 检查当前会话启用的角色:运行
SELECT CURRENT_ROLE() - 查用户完整权限(含继承自角色的):
SHOW GRANTS FOR 'alice'@'192.168.1.%'
回收权限时,“直授”和“角色继承”要分开处理
如果 alice 同时有直授的 SELECT ON logs.* 和通过角色继承的 INSERT ON myapp.*,那么 REVOKE INSERT ON myapp.* FROM 'alice'@'192.168.1.%' 只影响直授部分,对角色权限无效。要收掉角色赋予的权限,必须从角色本身下手:REVOKE INSERT ON myapp.* FROM 'dev_team',或者干脆 REVOKE 'dev_team' FROM 'alice'@'192.168.1.%'。
最容易忽略的一点:角色删除前必须先解除所有用户绑定,否则 DROP ROLE 'dev_team' 会失败并提示 ERROR 3529 (HY000): Cannot drop role 'dev_team' because it is granted to one or more users。


















