mysql数据库的权限继承与优先级管理

来源:这里教程网 时间:2026-02-28 20:38:00 作者:

MySQL 中权限是按层级叠加的,不是继承

MySQL 没有传统意义上的“权限继承”——比如给

db1.*
授予
SELECT
,不会自动让
db1.table1
获得额外权限;它只是把权限记录在
mysql.db
表里,作用范围更窄的权限(如表级、列级)会覆盖更宽泛的同名权限。真正起作用的是「匹配优先级」:MySQL 在验证权限时,按
host, user, db, table_name, column_name
从左到右逐级匹配,越具体的记录优先级越高。

全局权限(
GRANT ... ON *.*
)写入
mysql.user
,优先级最低
数据库级(
ON db1.*
)写入
mysql.db
,优先级中等
表级(
ON db1.t1
)写入
mysql.tables_priv
,优先级更高
列级(
ON db1.t1(col1)
)写入
mysql.columns_priv
,优先级最高

权限冲突时,MySQL 怎么决定用哪条记录?

当用户执行

SELECT col1 FROM db1.t1
,MySQL 会同时查多张权限表,并取各层级中「匹配且启用」的最高优先级记录。关键点在于:不是“叠加”,而是“取最大有效权限”。例如:

用户
'u1'@'localhost'
mysql.user
SELECT
全局权限 → 允许查所有库
同一用户在
mysql.db
db1
显式
DENY SELECT
(通过
GRANT USAGE
+ 单独
REVOKE
实现)→ 实际拒绝查
db1
再在
mysql.tables_priv
db1.t1
单独
GRANT SELECT
→ 此时仅对
t1
恢复可查

最终效果:查

db1.t2
报错,查
db1.t1
成功——因为表级权限覆盖了库级
DENY

REVOKE 不一定能撤销你认为的权限

REVOKE
只能撤销「当前作用域内显式授予的权限」,无法影响更高或更低层级的权限记录。常见误操作:

db1.*
GRANT SELECT
,然后在
db1.t1
REVOKE SELECT
→ 有效,
t1
权限被清除
*.*
GRANT SELECT
,然后在
db1.*
REVOKE SELECT
→ 无效!因为全局权限仍存在,用户依然能查
db1
想彻底禁用某用户对某个库的访问,必须确保:全局无权限 + 库级无权限 + 表级/列级也无残留记录

检查方式:

SELECT host,user,db,table_name,column_name,Select_priv FROM mysql.db WHERE user='u1' AND db='db1';
SELECT host,user,db,table_name,column_name,Select_priv FROM mysql.tables_priv WHERE user='u1' AND db='db1';

FLUSH PRIVILEGES 不是万能刷新开关

手动修改

mysql.*
系统表后,必须执行
FLUSH PRIVILEGES
才能让内存缓存更新;但用
GRANT
/
REVOKE
命令操作时,MySQL 自动完成持久化和加载,此时再执行
FLUSH PRIVILEGES
是冗余的,甚至可能掩盖权限未生效的真实原因(比如忘记
GRANT
后的
IDENTIFIED BY
密码不匹配)。

只在直接
INSERT/UPDATE
系统表后才需要
FLUSH PRIVILEGES
使用
GRANT
后权限立即生效(连接重连后可见),无需刷新
如果
GRANT
后权限不生效,先确认
user
host
是否完全匹配(注意
'u1'@'%'
'u1'@'localhost'
是两个不同账户)

权限生效依赖于连接时认证的

user@host
组合,这个组合一旦建立就不会再动态切换权限上下文——改完权限后,已有连接不会自动更新权限,必须断开重连。

相关推荐