授权层级与生效顺序是什么
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 没有「拒绝优先」的负向权限:想实现「除某库外全库只读」,需要为允许的范围逐库授予,或者拆成两个账号分别管理。这也是权限模型设计阶段就要考虑的事。
列级权限与表级权限叠加时行为更复杂:审计账号权限时要展开到列级检查,只看表级授权会漏掉部分可见列。