带您深入了解MySQL的权限管理

MySQL 的权限表在数据库启动的时候就载入内存,当用户通过身份认证后,就在内存中进行相应权限的存取,这样,此用户就可以在数据库中做权限范围内的各种操作了。

一、权限表的存取

在权限存取的两个过程中,系统会用到 “mysql” 数据库(安装 MySQL 时被创建,数据库名称叫“mysql”) 中 user、host 和 db 这3个最重要的权限表。

在这 3 个表中,最重要的表示 user 表,其次是 db 表,host 表在大多数情况下并不使用。

user 中的列主要分为 4 个部分:用户列、权限列、安全列和资源控制列。

通常用的最多的是用户列和权限列,其中权限列又分为普通权限和管理权限。普通权限用于数据库的操作,比如 select_priv、super_priv 等。

当用户进行连接时,权限表的存取过程有以下两个过程:

  • 先从 user 表中的 host、user 和 password 这 3 个字段中判断连接的 IP、用户名、和密码是否存在于表中,如果存在,则通过身份验证,否则拒绝连接。
  • 如果通过身份验证、则按照以下权限表的顺序得到数据库权限:user -> db -> tables_priv -> columns_priv。

在这几个权限表中,权限范围依次递减,全局权限覆盖局部权限。上面的***阶段好理解,下面以一个例子来详细解释一下第二阶段。

为了方便测试,需要修改变量 sql_mode

  1. // sql_mode 默认值中有 NO_AUTO_CREATE_USER (防止GRANT自动创建新用户,除非还指定了密码) 
  2.  
  3. SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' 

1. 创建用户 zj@localhost,并赋予所有数据库上的所有表的 select 权限

  1. MySQL [mysql]> grant select on *.* to zj@localhost; 
  2. Query OK, 0 rows affected, 2 warnings (0.00 sec) 
  3.  
  4. MySQL [mysql]> select * from user where user="zj" and host='localhost' \G; 
  5. *************************** 1. row *************************** 
  6.                   Host: localhost 
  7.                   User: zj 
  8.            Select_priv: Y 
  9.            Insert_priv: N 
  10.            Update_priv: N 
  11.            Delete_priv: N 
  12.            Create_priv: N 
  13.              Drop_priv: N 
  14.            Reload_priv: N 
  15. ...  

2. 查看 db 表

  1. MySQL [mysql]> select * from db where user='zj' \G ; 
  2.  
  3. Empty set (0.00 sec)  

可以发现,user 表的 select_priv 列是 “Y”,而 db 表中并没有记录,也就是说,对所有数据库都具有相同的权限的用户并不需要记录到 db 表,而仅仅需要将 user 表中的 select_priv 改为 “Y” 即可。换句话说,user 表中的每个权限都代表了对所有数据库都有权限。

3. 将 zj@localhost 上的权限改为只对 t2 数据库上所有表的 select 权限。

  1. MySQL [mysql]> revoke select on *.* from zj@localhost; 
  2. Query OK, 0 rows affected, 1 warning (0.02 sec) 
  3.  
  4. MySQL [mysql]> grant select on t2.* to zj@localhost; 
  5. Query OK, 0 rows affected, 1 warning (0.04 sec) 
  6.  
  7. MySQL [mysql]> select * from user where user='zj' \G; 
  8. *************************** 1. row *************************** 
  9.                   Host: localhost 
  10.                   User: zj 
  11.            Select_priv: N 
  12.            Insert_priv: N 
  13.            Update_priv: N 
  14.            Delete_priv: N 
  15.            Create_priv: N 
  16.              Drop_priv: N 
  17.            Reload_priv: N 
  18. ... 
  19.  
  20. MySQL [mysql]> select * from db where user='zj' \G; 
  21. *************************** 1. row *************************** 
  22.                  Host: localhost 
  23.                    Db: t2 
  24.                  User: zj 
  25.           Select_priv: Y 
  26.           Insert_priv: N 
  27.           Update_priv: N 
  28.           Delete_priv: N 
  29.           Create_priv: N 
  30.             Drop_priv: N 
  31.            Grant_priv: N  

这时候发现,user 表中的 select_priv 变为 “N” ,而 db 表中增加了 db 为 t2 的一条记录。也就是说,当只授予部分数据库某些权限时,user 表中的相应权限列保持 “N”,而将具体的数据库权限写入 db 表。table 和 column 的权限机制和 db 类似。

从上例可以看出,当用户通过权限认证,进行权限分配时,将按照 user -> db -> tables_priv -> columns_priv 的顺序进行权限分配,即先检查全局权限表 user,如果 user 中对应 权限为 “Y”,则此用户对所有数据库的权限都为“Y”,将不再检查 db、tables_priv 和 columns_priv;如果为“N”,则到 db 表中检查此用户对应的具体数据库,并得到 db 中为 “Y”的权限;如果 db 中相应权限为 “N”,则再依次检查tables_priv 和 columns_priv 中的权限,如果所有的都为“N”,则判断为不具备权限。

二、账号管理

主要包括账号的创建,权限的更改和账号的删除。

1. 创建账号

使用 grant 语法创建,示例:

(1) 创建用户 zj ,权限为可以在所有数据库上执行所有权限,只能从本地进行连接。

  1. MySQL [mysql]> grant all privileges on *.* to zj@localhost; 
  2. Query OK, 0 rows affected, 2 warnings (0.00 sec) 
  3.  
  4. MySQL [mysql]> select * from user where user="zj" and host="localhost" \G; 
  5. *************************** 1. row *************************** 
  6.                   Host: localhost 
  7.                   User: zj 
  8.            Select_priv: Y 
  9.            Insert_priv: Y 
  10.            Update_priv: Y 
  11.            Delete_priv: Y 
  12.            Create_priv: Y 
  13.              Drop_priv: Y 
  14.            Reload_priv: Y 
  15.          Shutdown_priv: Y  

可以发现,除了 grant_priv 权限外,所有权限在 user 表里面都是 “Y”。

(2) 在 (1) 基础上,增加对 zj 的 grant 权限

  1. MySQL [(none)]> grant all privileges on *.* to zj@localhost with grant option
  2. Query OK, 0 rows affected, 1 warning (0.01 sec) 
  3.  
  4. MySQL [mysql]> select * from user where user="zj" and host='localhost' \G ; 
  5. *************************** 1. row *************************** 
  6.                   Host: localhost 
  7.                   User: zj 
  8.            Select_priv: Y 
  9.            Insert_priv: Y 
  10.            Update_priv: Y 
  11.            Delete_priv: Y 
  12.            Create_priv: Y 
  13.              Drop_priv: Y 
  14.            Reload_priv: Y 
  15.          Shutdown_priv: Y 
  16.           Process_priv: Y 
  17.              File_priv: Y 
  18.             Grant_priv: Y 
  19. ...  

(3) 在 (2) 基础上,设置密码为 “123”

  1. MySQL [mysql]> grant all  privileges on *.* to zj@localhost identified by '123' with grant option
  2. Query OK, 0 rows affected, 2 warnings (0.01 sec) 
  3.  
  4. MySQL [mysql]> select * from user where user="zj" and host="localhost" \G ; 
  5. *************************** 1. row *************************** 
  6.                   Host: localhost 
  7.                   User: zj 
  8.            Select_priv: Y 
  9.            Insert_priv: Y 
  10.            Update_priv: Y 
  11.            Delete_priv: Y 
  12.            Create_priv: Y 
  13.              Drop_priv: Y 
  14.            Reload_priv: Y 
  15. ......   
  16.  authentication_string: *23AE809DDACAF96AF0FD78ED04B6A265E0***A257 
  17.       password_expired: N 
  18.  password_last_changed: 2017-09-25 20:29:42 
  19.      password_lifetime: NULL  

可以发现,密码变成了一堆加密后的字符串。

(4) 创建新用户 zj2,可以从任何 IP 连接,权限为对 t2 数据库里的所有表进行 select 、update、insert 和 delete 操作,初始密码为“123”

  1. MySQL [mysql]> grant select ,insert, update,delete on t2.* to 'zj2'@'%' identified by '123'; 
  2. Query OK, 0 rows affected, 1 warning (0.00 sec) 
  3.  
  4. MySQL [mysql]> select * from user where user='zj2' and host="%" \G; 
  5. *************************** 1. row *************************** 
  6.                   Host: % 
  7.                   User: zj2 
  8.            Select_priv: N 
  9.            Insert_priv: N 
  10.            Update_priv: N 
  11.            Delete_priv: N 
  12.            Create_priv: N 
  13.              Drop_priv: N 
  14. ...... 
  15.  authentication_string: *23AE809DDACAF96AF0FD78ED04B6A265E0***A257 
  16.       password_expired: N 
  17.  password_last_changed: 2017-09-25 20:37:49 
  18.      password_lifetime: NULL 
  19.  
  20. MySQL [mysql]> select * from db where user="zj2" and host='%' \G; 
  21. *************************** 1. row *************************** 
  22.                  Host: % 
  23.                    Db: t2 
  24.                  User: zj2 
  25.           Select_priv: Y 
  26.           Insert_priv: Y 
  27.           Update_priv: Y 
  28.           Delete_priv: Y 
  29.           Create_priv: N 
  30.             Drop_priv: N 
  31. ......  

user 表中的权限都是“N”,db 表中增加的记录权限则都是“Y”。一般的,只授予用户适当的权限,而不会授予过多的权限。

本例中的 IP 限制为所有 IP 都可以连接,因此设置为 “*”,mysql 数据库中是通过 user 表的 host 字段来进行控制,host 可以是以下类型的赋值。

  • Host 值可以是主机名或IP号,或 “localhost” 指出本地主机。
  • 可以在 Host 列值使用通配符字符 “%” 和 “_”
  • Host 值 “%” 匹配任何主机名,空 Host 值等价于 “%”,它们的含义与 like 操作符的模式匹配操作相同。

注意: mysql 数据库的 user 表中 host 的值为 “*” 或者空,表示所有外部 IP 都可以连接,但是不包括本地服务器 localhost,因此,如果要包括本地服务器,必须单独为 localhost 赋予权限。

(5) 授予 super、process、file 权限给用户 zj3@%

  1. MySQL [mysql]> grant super,process,file on *.* to 'zj3'@'%'
  2.  
  3. Query OK, 0 rows affected, 1 warning (0.00 sec)  

因为这几个权限都是属于管理权限,因此不能够指定某个数据库,on 后面必须跟 “.”,下面语法将提示错误

  1. MySQL [mysql]> grant super,process,file on t2.* to 'zj3'@'%'
  2.  
  3. ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES  

(6) 只授予登录权限给 zj4@localhost

  1. MySQL [mysql]> grant usage on *.* to 'zj4'@'localhost'
  2. Query OK, 0 rows affected, 2 warnings (0.01 sec) 
  3.  
  4. MySQL [mysql]> exit 
  5. Bye 
  6.  
  7. zj@bogon:~$ mysql -uzj4 -p 
  8. Enter password:  
  9. Welcome to the MySQL monitor.  Commands end with ; or \g. 
  10. Your MySQL connection id is 78 
  11. Server version: 5.7.18-log Source distribution 
  12.  
  13. Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. 
  14.  
  15. Oracle is a registered trademark of Oracle Corporation and/or its 
  16. affiliates. Other names may be trademarks of their respective 
  17. owners. 
  18.  
  19. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 
  20.  
  21. MySQL [(none)]> show databases; 
  22. +--------------------+ 
  23. Database           | 
  24. +--------------------+ 
  25. | information_schema | 
  26. +--------------------+ 
  27. 1 row in set (0.02 sec)  

usage 权限只能用于数据库登录,不能执行任何操作

2. 查看账号权限

账号创建好后,可以通过如下命令查看权限:

  1. show grants for user@host; 

示例:

  1. MySQL [(none)]> show grants for zj@localhost; 
  2. +-------------------------------------------------------------------+ 
  3. | Grants for zj@localhost                                           | 
  4. +-------------------------------------------------------------------+ 
  5. GRANT ALL PRIVILEGES ON *.* TO 'zj'@'localhost' WITH GRANT OPTION | 
  6. +-------------------------------------------------------------------+ 
  7. 1 row in set (0.01 sec)  

3. 更改账号权限

可以进行权限的新增和回收。和创建账号一样,权限变更也有两种方法:使用 grant(新增) 和 revoke (回收) 语句,或者更改权限表。

示例:

(1) zj4@localhost 目前只有登录权限

  1. MySQL [(none)]> show grants for zj4@localhost; 
  2. +-----------------------------------------+ 
  3. | Grants for zj4@localhost                | 
  4. +-----------------------------------------+ 
  5. GRANT USAGE ON *.* TO 'zj4'@'localhost' | 
  6. +-----------------------------------------+ 
  7. 1 row in set (0.00 sec)  

(2) 赋予 zj4@localhost 所有数据库上的所有表的 select 权限

  1. MySQL [(none)]> grant select on *.* to 'zj4'@'localhost'
  2. Query OK, 0 rows affected, 1 warning (0.00 sec) 
  3.  
  4. MySQL [(none)]> show grants for zj4@localhost; 
  5. +------------------------------------------+ 
  6. | Grants for zj4@localhost                 | 
  7. +------------------------------------------+ 
  8. GRANT SELECT ON *.* TO 'zj4'@'localhost' | 
  9. +------------------------------------------+ 
  10. 1 row in set (0.00 sec)  

(3) 继续给 zj4@localhost 赋予 select 和 insert 权限,和已有的 select 权限进行合并

  1. MySQL [(none)]> show grants for 'zj4'@'localhost'
  2. +--------------------------------------------------+ 
  3. | Grants for zj4@localhost                         | 
  4. +--------------------------------------------------+ 
  5. GRANT SELECTINSERT ON *.* TO 'zj4'@'localhost' | 
  6. +--------------------------------------------------+ 
  7. 1 row in set (0.00 sec)  

revoke 语句可以回收已经赋予的权限,对于上面的例子,这里决定要收回 zj4@localhost 上的 insert 和 select 权限:

  1. MySQL [(none)]> revoke select,insert on *.* from zj4@localhost; 
  2. Query OK, 0 rows affected, 1 warning (0.00 sec) 
  3.  
  4. MySQL [(none)]> show grants for zj4@localhost; 
  5. +-----------------------------------------+ 
  6. | Grants for zj4@localhost                | 
  7. +-----------------------------------------+ 
  8. GRANT USAGE ON *.* TO 'zj4'@'localhost' | 
  9. +-----------------------------------------+ 
  10. 1 row in set (0.00 sec)  

usage 权限不能被回收,也就是说,revoke 用户并不能删除用户。

4. 修改账号密码

(1) 可以用 mysqladmin 命令在命令行指定密码。

  1. shell> mysqladmin -u user_name -h host_name password "123456" 

(2) 执行 set password 语句。

  1. mysql> set password for 'username'@'%' = password('pwd'); 

如果是更改自己的密码,可以省略 for 语句

  1. mysql> set password=password('pwd'); 

(3) 可以在全局级别使用 grant usage 语句(在“.”)来指定某个账户的密码而不影响账户当前的权限。

  1. mysql> grant usage on *.* to 'username'@'%' identified by 'pwd'

5. 删除账号

要彻底的删除账号,可以使用 drop user :

  1. drop user zj@localhost; 

6. 账号资源限制

创建 MySQL 账号时,还有一类选项称为账号资源限制,这类选项的作用是限制每个账号实际具有的资源限制,这里的“资源”主要包括:

  • max_queries_per_hour count : 单个账号每小时执行的查询次数
  • max_upodates_per_hour count : 单个账号每小时执行的更新次数
  • max_connections_per_hour count : 单个账号每小时连接服务器的次数
  • max_user_connections count : 单个账号并发连接服务器的次数 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/253620.html<

(0)
管理的头像管理
上一篇2025-04-29 23:58
下一篇 2025-04-29 23:59

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注