首页/数据/数据库速查/授权层级与生效顺序(user → db → tables_priv → 会话)

授权层级与生效顺序(user → db → tables_priv → 会话)

权限校验顺序:全局权限 → 库权限 → 表/列权限逐层合并,最终取并集;理解层级才能解释「为什么只授了库权限却能查表」。

数据库速查数据更新于 2026-10-13

授权层级与生效顺序是什么

MySQL 的权限按层级存放:全局(*.*)、库(库.*)、表(库.表)、列。校验时自上而下逐层合并,最终取并集——没有任何一条规则能否决已授予的权限。理解这一点才能解释日常困惑:只授了库级权限却能查表,是因为库级权限覆盖了该库下所有表;而「除了某个库以外全库只读」这种需求无法用一条授权表达,只能靠枚举授权或拆分账号实现。

基本信息

层级顺序全局 *.* → 库 库.* → 表 库.表 → 列
生效方式并集累加,没有负向(拒绝)权限
查看SHOW GRANTS FOR '账号'@'主机',输出按层级分行
回收REVOKE 对应层级的权限,需与授予时写法一致
常见误区以为高层次权限会自动覆盖或限制低层次权限

典型使用场景

  • 权限审计:逐行读 SHOW GRANTS 输出,判断账号实际能力边界
  • 最小权限设计:把库级权限收敛到具体表,降低误操作影响面
  • 排障:解释为什么某个账号能查询它「看起来不该有权限」的表
  • 权限回收:确认 REVOKE 的层级与对象,避免撤错范围
  • 账号拆分:需要「除某库外只读」这类需求时改用多个账号组合

层级演示

层级演示
-- 全局只读
GRANT SELECT ON *.* TO 'r1'@'10.0.%';
-- 叠加一个库的写权限(并集,不是覆盖)
GRANT SELECT, UPDATE ON appdb.* TO 'r1'@'10.0.%';
-- 查看结果:输出按层级分行,要逐行读
SHOW GRANTS FOR 'r1'@'10.0.%';
-- 收敛到表级更小的范围
GRANT SELECT ON appdb.orders TO 'o1'@'10.0.5.7';
-- 回收时保持与授予时相同的层级写法
REVOKE UPDATE ON appdb.* FROM 'r1'@'10.0.%';

层级与含义

层级写法影响范围
全局ON *.*实例内所有库表
库ON 库.*该库下所有表
表ON 库.表单张表
列GRANT ... (列名) ON 库.表仅指定列,叠加关系更复杂
MySQL 没有「拒绝优先」的负向权限:想实现「除某库外全库只读」,需要为允许的范围逐库授予,或者拆成两个账号分别管理。这也是权限模型设计阶段就要考虑的事。
列级权限与表级权限叠加时行为更复杂:审计账号权限时要展开到列级检查,只看表级授权会漏掉部分可见列。

易错点

  • 以为高优先级层级会限制低层级权限:实际是并集累加,只授库级权限即可覆盖该库全部表
  • 用 REVOKE 实现「只排除一个库」:做不到,必须拆账号或改授权设计
  • 只读 SHOW GRANTS 第一行就下结论:输出按层级分行,漏读会误判账号实际权限
  • REVOKE 写法与授予时不一致:层级或对象不匹配导致回收无效,需要复查确认
  • 给应用账号全局只读再加库级写:权限范围被意外放大,账号一旦被误用影响面覆盖整个实例

数据来源与参考

  • MySQL 8.0 Reference Manual: Access Control, Stage 2: Request Verification

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌