MySQL 采用一种层次化的权限管理系统,除了最高级别的 `user` 表,还有更细粒度的权限控制表。当检查一个用户是否能执行某项操作时,MySQL 会按照一个特定的顺序进行权限检查。

 

为了更直观地理解这个过程,我们可以参考以下权限检查流程图:

mermaid

flowchart TD

A[用户发起操作请求] --> B{权限检查}

 

B -- 全局权限 --> C[检查 user 表]

C -- 拥有该全局权限? --> D{是}

 

B -- 数据库级权限 --> E[检查 db 表]

E -- 拥有该数据库权限? --> D

 

B -- 表级权限 --> F[检查 tables_priv 表]

F -- 拥有该表权限? --> D

 

B -- 列级权限 --> G[检查 columns_priv 表]

G -- 拥有该列权限? --> D

 

B -- 子程序权限 --> H[检查 procs_priv 表]

H -- 拥有该程序权限? --> D

 

D --> I[允许操作]

   

C -- 否<br>且无下级表记录?<br>或下级表检查未通过? --> J[拒绝操作]

E -- 否 --> J

F -- 否 --> J

G -- 否 --> J

H -- 否 --> J

 

从以上可以看出,MySQL 的权限检查是累加的。只要在任何一个层级被明确授予了权限,操作就会被允许。

 

各权限表功能详解

1.  `db` 表 (数据库级权限)

    作用:存储用户对**特定数据库**的操作权限。是实现“用户A只能操作数据库B”的关键。

    用户列:`Host`, `User`, `Db`。这三列共同构成主键,定义了“哪个用户从哪台主机来,对哪个数据库”有权限。

    权限列:与 `user` 表类似(如 `Select_priv`, `Create_priv`),但这里的权限**仅适用于**`Db`字段指定的数据库。

    使用场景:开发人员、应用账户通常只被授予一两个数据库的权限,而非全局权限。

 

2.  `tables_priv` 表 (表级权限)

    作用:控制用户对特定表的权限。权限比 `db` 表更细化。

    关键字段:

           `Host`, `User`, `Db`, `Table_name` (共同定位到一张表)

           `Table_priv`:定义对表的操作权限,数据类型是 `SET`,可以同时指定多个权限(如 `'Select,Insert,Update'`)。

           `Column_priv`:**预告**该用户在此表上是否拥有任何列级权限。

    使用场景:限制用户只能访问某个数据库中的某几张表。

 

3.  `columns_priv` 表 (列级权限)

    作用:控制用户对特定列的权限。这是最细粒度的权限控制之一。

    关键字段:

           `Host`, `User`, `Db`, `Table_name`, `Column_name` (共同定位到一个列)

           `Column_priv`:定义对列的操作权限(`SELECT`, `INSERT`, `UPDATE`, `REFERENCES`)。

    使用场景:保护敏感数据。例如,允许用户查看 `employees` 表的 `name`、`department` 列,但不能查看 `salary` 列。

 

4.  `procs_priv` 表 (子程序权限)

    作用:控制用户对存储过程(PROCEDURE)和存储函数(FUNCTION) 的权限。

    关键字段:

           `Host`, `User`, `Db`, `Routine_name`, `Routine_type` (共同定位到一个子程序)

           `Proc_priv`:拥有的权限,主要是 `Execute`(执行)、`Alter Routine`(修改)、`Grant`(授权)。

    使用场景:管理存储过程和函数的执行权限,实现更复杂的业务逻辑封装和权限控制。

 

总结与最佳实践

1.  权限原则:遵循最小权限原则,用户只应获得其必要的最小权限。

2.  授权方式:永远使用 `GRANT` 和 `REVOKE` 语句来管理权限,而不是直接对权限表进行 `INSERT`/`UPDATE`。SQL 语句更安全,且会自动刷新权限缓存。

     授予数据库级权限

GRANT SELECT, INSERT ON `mydb`.* TO 'app_user'@'%';

     授予表级权限

GRANT SELECT ON `mydb`.`sensitive_table` TO 'report_user'@'localhost';

     授予列级权限

 GRANT SELECT (id, name), UPDATE (name) ON `mydb`.`users` TO 'operator'@'%';

     授予执行权限

  GRANT EXECUTE ON PROCEDURE `mydb`.`calculate_bonus` TO 'hr_user'@'%';


3.  权限生效:使用 `FLUSH PRIVILEGES;` 命令可使手动修改权限表后的更改立即生效(但 `GRANT`/`REVOKE` 不需要此操作)。

4.  权限检查顺序:如流程图所示,MySQL 会从最宽泛的 `user` 表到最精确的 `columns_priv` 表依次检查,一旦在某一级被允许,即通过。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)