@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Calibri"; } p.MsoNormal{ mso-style-name:正文; mso-style-parent:""; margin:0pt; margin-bottom:.0001pt; mso-pagination:none; text-align:justify; text-justify:inter-ideograph; font-family:Calibri; mso-fareast-font-family:宋体; mso-bidi-font-family:'Times New Roman'; font-size:10.5000pt; mso-font-kerning:1.0000pt; } p.MsoHeader{ mso-style-name:页眉; margin:0pt; margin-bottom:.0001pt; border-top:none; mso-border-top-alt:none; border-right:none; mso-border-right-alt:none; border-bottom:none; mso-border-bottom-alt:none; border-left:none; mso-border-left-alt:none; padding:1pt 4pt 1pt 4pt ; layout-grid-mode:char; mso-pagination:none; text-align:justify; text-justify:inter-ideograph; font-family:Calibri; mso-fareast-font-family:宋体; mso-bidi-font-family:'Times New Roman'; font-size:9.0000pt; mso-font-kerning:1.0000pt; } p.MsoFooter{ mso-style-name:页脚; margin:0pt; margin-bottom:.0001pt; layout-grid-mode:char; mso-pagination:none; text-align:left; font-family:Calibri; mso-fareast-font-family:宋体; mso-bidi-font-family:'Times New Roman'; font-size:9.0000pt; mso-font-kerning:1.0000pt; } span.msoIns{ mso-style-type:export-only; mso-style-name:""; text-decoration:underline; text-underline:single; color:blue; } span.msoDel{ mso-style-type:export-only; mso-style-name:""; text-decoration:line-through; color:red; } @page{mso-page-border-surround-header:no; mso-page-border-surround-footer:no;}@page Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:595.3000pt 841.9000pt; layout-grid:15.6000pt; mso-header-margin:42.5500pt; mso-footer-margin:49.6000pt; mso-page-numbers:decimal; } div.Section0{page:Section0;}
# 学习目标
```
MySQL是一个多用户数据库,具有功能强大的访问控制系统,可以为不同的用户指定允许的权限。
MySQL用户分为root用户和普通用户,root用户是超级管理员,拥有所有权限,包括创建用户、删除用户和修改用户的密码等管理权限;普通用户只拥有被授予的各种权限。
用户管理包括管理用户账户、权限等。
```
## 一、权限表
```
MySQL服务器通过权限表来控制用户对数据的访问,权限表存放在mysql数据库中,由mysql_install_db脚本初始化。
存储账户权限信息表主要有:user、db、host(5.7中没有)、tables_priv、columns_priv、和procs_priv。
columns [ˈkɑːləm] n.列
mysql> use mysql;
mysql> show tables;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| engine_cost |
| event |
| func |
| general_log |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| ndb_binlog_index |
| plugin |
| proc |
| procs_priv |
| proxies_priv |
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
31 rows in set (0.00 sec)
```
### 1. user 表
```
user表是MySQL中最重要的一个权限表,记录允许连接到服务器的账号信息,里面的授权是全局级的。
例如:一个用户在user表中被授予了delete权限,则该用户可以删除MySQL服务器上所有数据库中的任何记录。
user表中有45个字段,这些字段可以分为4类,分别是:用户列、权限列、安全列、资源控制列。
```
#### 1.1 用户列
```
user表中用户列包括:Host、User、authentication_string,分别表示主机名、用户名和密码,其中Host和User为user表的联合主键。
当用户与服务器之间建立连接的时,输入的账户信息中的用户名、主机名和密码必须匹配user表中对应的字段,只有三个值都匹配的时候才可以连接。
Host、User、authentication_string这三个字段的值是创建用户的时候保存的账户信息,修改密码时实际修改的就是user表中的authentication_string字段的值。
authentication [ɔːˌθentɪˈkeɪʃn] n.身份验证,认证。
privileges [ˈprɪvəlɪdʒɪz] n.权限
```
#### 1.2 权限列
```
权限列决定了用户的权限,描述了在全局范围内允许对数据和数据库进行的操作。
包括查询权限、修改权限等普通权限,还包括关闭服务器、超级权限和加载用户等高级权限。
普通权限用于操作数据库;高级权限用于数据库管理。
权限列字段的值的类型是ENUM,可以取得值只能是Y和N,Y表示该用户有对应的权限,N表示没有对应的权限。
可以使用Grant和update语句更改这些字段来修改用户对应的权限。
```
#### 1.3 安全列
```
安全列只有6个,两个是ssl相关的,两个是x509相关的,另外两个是授权插件相关的。
ssl用于加密;x509标准可用于表示用户;
用户可使用show variables like 'have_openssl';语句来查看服务器手否支持ssl功能。
```
#### 1.4 资源控制列
```
资源控制列的字段用于限制用户使用的资源,包含四个字段,分别是:
max_questions 用户每小时允许执行的查询操作次数;
max_updates 用户每小时允许执行的更新操作次数;
max_connections 用户每小时允许执行的连接操作次数;
max_user_connections 用户允许同时建立的连接次数;
一个小时内用户查询或者连接数量超过资源控制限制用户将被锁定,直到下一个小时才可以执行对应的操作。
可以使用grant语句更新这些字段的值。
```
### 2. db 表和host 表
```
db表和host表是mysql数据库中非常重要的权限表。db表中存储了用户对某个数据库的操作权限,决定用户能从哪个主机存取哪个数据库。
host表中存储了某个主机对数据库的操作权限,配合db表对给定主机上的数据库级操作权限做更细致的控制。这个表不受grant和revoke语句的影响。
db表常用而host表很少用。db表和host表结构相似,字段大致分为两类:用户列和权限列。
1.用户列
db表用户列有3个字段,分别是Host、Db、User,标识从某个主机连接某个用户对某个数据库的权限,这3个字段的组合构成了db表的主键。
2.权限列
db表和host表权限列大致相同,表中create_routine_priv和alter_routine_priv这两个字段表明用户是否有创建和修改存储过程的权限。
user表中的权限是针对所有数据库的,如果希望用户只对某个数据库具有操作权限,那么需要将user表中对应的权限设置为N,然后在db表中设置对应数据库的操作权限。
```
### 3. tables_priv 表和columns_priv 表
```
columns [ˈkɑːləm] n.列
privilege [ˈprɪvəlɪdʒ] n.权限
tables_priv 表,用来对表设置操作权限,columns_priv表,用来对表中的某一列设置权限。
```
### 4. procs_priv 表
```
procs_priv 表可以对存储过程和存储函数设置操作权限。
```
## 二、账户管理
### 1. 登录和退出MySQL
```
mysql --help命令可以查看mysql命令帮助信息,常用参数如下:
(1) -h 可以使用该参数指定主机名/ip(用来登录mysql的服务器地址),若不指定默认是localhost。
(2) -u 用户名,可以使用该参数指定用户名。
(3) -p 密码,可以使用该参数指定用户的登录密码,注意后面的字符串和-p之间不能有空格。
(4) -P 端口号,该参数后面接MySQL的端口号,默认为3306。
(5) 数据库名 可以在命令最后指定数据库名。
(6) -e 执行SQL语句,如果指定了该参数,将在登录后执行-e后面的命令或者SQL语句并退出,适用于脚本中。
范例:
1. 使用root用户登录到本地的MySQL服务器的test库中。
[root@Study ~]# mysql -h localhost -u root -p123456 test
2. 使用root用户登录到本地的MySQL服务器的test库中并查看当前所在的库。
[root@Study ~]# mysql -h localhost -u root -p123456 test -e 'select database();'
【查看当前登录的用户】
mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| root@% |
+----------------+
```
### 2. 新建普通用户
```
方法一:使用create user或grant语句;
方法二:直接使用root用户在user表中插入记录(不推荐);
常见符号:
1. \g 的作用和sql语句中写';'是等效的;
2. \G 的作用是将查到的结构旋转90度变成纵向;
3. 主机地址可以使用'%'或者''代替,表示无限制;
4. 192.168.41.% 表示192.168.41.0/24网段;
```
#### 2.1 使用create user语句创建新用户(推荐)
```
1. 语法:
create user '用户名'@'主机地址' identified by '密码';
2. 范例:
<1>.创建用户test01,设置密码为123456,且登录不受限制。
mysql> create user 'test01'@'%' identified by '123456';
<2>.创建用户test02,设置密码为123456,且仅允许192.168.41段登录。
mysql> create user 'test02'@'192.168.41.%' identified by '123456';
3. 说明:
mysql> show grants for 'cui'@'%';
+---------------------------------+
| Grants for cui@% |
+---------------------------------+
| GRANT USAGE ON *.* TO 'cui'@'%' |
+---------------------------------+
1 row in set (0.00 sec)
使用create user语句创建的用户没有任何权限,还需要使用grant语句赋予用户权限。
usage 权限只能用于数据库登陆,不能执行任何操作;且usage权限不能被回收。
```
#### 2.2 使用grant语录创建新用户(不推荐)
```
1. 语法:
GRANT privileges ON db.table TO user@host IDENTIFIED BY 'password';
-privileges 表示要赋予用于的权限;
-db.table 表示用户的权限所作用的数据库中的表;
-password 表示给用户设置的密码;
2. 范例:
<1>.创建用户test,密码为123,并授予对所有库和表具有select和update权限。
mysql> grant select,update on *.* to 'test'@'localhost' identified by '123456';
<2>.创建用户cui,密码为123,并授予对所有库和表具有select和update权限,且值能在192.168.40网段上登录。
mysql> grant select,update on *.* to 'cui'@'192.168.40.%' identified by '123';
<3>.创建用户bin,密码为123,并授予仅对mysql.user表具有select权限,且只能在192.168.0.5上登录。
mysql> grant select on mysql.user to 'bin'@'192.168.0.5' identified by '123';
注释:使用mysql> show warnings; 可以查看警告内容。
```
### 3. 删除普通用户
```
可以使用drop user语句删除用户,也可以使用delete语句从mysql.user表中删除对应的记录来删除用户。
```
#### 3.1 使用drop user语句删除用户
```
1. 语法:
drop user '用户名'@'主机名';
2. 范例:
<1>.删除用户test。
mysql> drop user 'test'@'%';
3. 说明:
<1>.drop user语句用于删除一个或多个用户,并撤销其权限。
<2>.在drop user语句中,若没有明确指出用户的主机名,则该主机名默认为'%'。
<3>.drop user不能自动关闭任何打开的用户对话。而且,用户有打开的对话,此时取消用户命令则不会生效,
直到用户对话被关闭后才能生效。一旦对话被关闭用户也被取消,此时用户再试图登录将会失败。
```
#### 3.2 使用delete语句删除用户
```
1. 语法:
DELETE FROM mysql.user WHERE host='hostname' and user='username';
2. 范例:
<1>.删除用户test。
mysql> delete from mysql.user where host='%' and user='test';
说明:其中host和user为user表中的两个字段,两个字段的组合确定所要删除的账户记录。
```
### 4. root用户修改自己的密码
#### 4.1 使用alter user语句修改root密码(首选)
```
1. 语法:alter user '用户'@'主机名' identified by '新密码';
2. 范例:
<1>.使用alte user将账号'root'@'%'的密码修改为cui123。
mysql> alter user 'root'@'%' identified by 'cui123';
```
#### 4.2 使用mysqladmin命令在命令行指定新密码
```
1. 语法:
mysqladmin -uroot [-hlocalhost] -p当前密码 password |空格| '新密码'
-h 指定要修改的对应哪个主机用户的密码,不写则默认localhost;
-p 表示输入当前密码;password为关键字,后面引号里为设置的新密码。
2. 范例:
<1>.使用mysqladmin将root用户的密码改为123456
[root@Study ~]# mysqladmin -uroot -p123456 password '123456'
<2>.使用mysqladmin将root用户的密码改为112233(根据提示输入新密码即可)
[root@Study ~]# mysqladmin -uroot -p123456 password
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
New password:
Confirm new password:
```
#### 4.3 使用set语句修改root用户的密码
```
1. 语法:
set password [for 'user'@'localhost'] = password('新密码');
mysql5.6:set password=password('新密码'); #修改当前用户的密码
mysql5.7:set password='新密码'; #修改当前用户的密码
2. 范例:
<1>.将root用户的密码修改为123456。
mysql> set password='123456';
#修改指定用户的密码
mysql> set password for 'root'@'%'='123456';
3. 重要说明:
在某些情况下,set password 可能会记录在服务器日志中或在客户端的历史文件中,
例如 ~/.mysql_history,这意味着任何对该信息具有读取权限的人都可以读取明文密码。
```
#### 4.4 使用update修改mysql.user表
```
1. 语法:
mysql5.6:update mysql.user set password=password('新密码') where user='root' and host='localhost';
mysql5.7:update mysql.user set authentication_string=password('新密码') where user='root' and host='localhost';
-password()对密码进行哈希处理;
-执行update语句后需要执行flush privileges;语句重新加载用户权限。
2. 范例:
<1>.将root用户的密码修改为123。
mysql> update mysql.user set authentication_string=password('123') where user='root' and host='localhost';
mysql> flush privileges;
```
### 5. root用户修改普通用户的密码
#### 5.1 使用 alter user 语句修改普通用户的密码(首选)
```
1. 语法:alter user '用户'@'主机名' identified by '新密码';
2. 范例:
<1>.使用alte user将账号'abc'@'%'的密码修改为cui123。
mysql> alter user 'abc'@'%' identified by 'cui123';
```
#### 5.2 使用set语句修改普通用户的密码
```
1. 语法:
mysql5.6:set password for 'user'@'hostname'=password('新密码');
mysql5.7:set password for 'user'@'hostname'='新密码';
2. 范例:
<1>.使用set语句将test用户的密码修改为123.
mysql5.6> set password for 'test'@'%'=password('123456');
mysql5.7> set password for 'test'@'%'='123';
```
#### 5.3 使用update语句修改普通用户的密码(有警告)
```
1. 语法:
mysql5.6:uptade mysql.user set password=password('新密码') where user='username' and host='hostname';
mysql5.7:uptade mysql.user set authentication_string=password('新密码') where user='username' and host='hostname';
-password()对密码进行哈希处理;
-执行update语句后需要执行flush privileges;语句重新加载用户权限。
2. 范例:
<1>.将普通用户的test的密码设置为789456。
mysql> update mysql.user set authentication_string=password('789456') where user='test' and host='%';
mysql> flush privileges;
```
### 6. 普通用户修改自己的密码
#### 6.1 使用alter user语句修改密码
```
mysql> alter user 'abc'@'%' identified by '123';
```
#### 6.2 使用set修改密码
```
普通用户登录MySQL服务器后,通过set语句设置自己的密码。
语法:
mysql5.6:set password=password('新密码');
mysql5.7:set password='新密码';
语法:set password [for 'user'@'host']='新密码';
```
### 7. root密码丢失
```
方法:root密码丢失后可以使用--skip-grant-tables选项启动MySQL服务,然后重置密码。
说明:以--skip-grant-tables选项启动时,MySQL服务器将不加载权限判断,任何用户都能访问数据库。
【windows操作系统】
在windows操作系统中,可以使用mysqld或mysqld-nt来启动mysql服务进程。
如果MySQL的目录已经添加到系统环境变量中,可以直接使用mysqld、mysqld-nt命令启动mysql服务,否则需要先切换到mysql的bin目录。
1.关掉mysql服务
2.使用--skip-grant-tables参数启动mysql
<1>.mysqld命令如下:
mysqld --skip-grant-tables
<2>.mysqld-nt命令如下:
mysqld-nt --skip-grant-tables
3.启动mysql服务后,就可以使用root用户免密登录了,然后使用update语句修改密码(alter user、set语句不行)。
4.修改密码完成后关掉使用--skip-grant-tables启动的mysql,然后重启mysql服务,之后就可以使用新密码登录了。
【linux操作系统】
在linux操作系统中,可以使用/etc/init.d/mysql.server或mysqld_safe命令来启动mysql服务。
1.关掉mysql服务
2.使用--skip-grant-tables参数启动mysql
<1>.若使用/etc/init.d/mysql.server命令,则如下:(推荐)
[root@MySQL5 ~]# /etc/init.d/mysql.server start --skip-grant-tables
<2>.若使用mysqld_safe命令,则如下:
[root@MySQL5 ~]# mysqld_safe --skip-grant-tables user=mysql
3.启动mysql服务后,就可以使用root用户免密登录了,然后使用update语句修改密码(alteruser、set语句不行)。
注意:mysl8.x使用update语句修改密码会报错,可使用以下方法:
a.先将root密码修改为空
mysql:uptade mysql.user set authentication_string='' where user='username' and host='hostname';
mysql: flush privileges;
b.去掉--skip-grant-tables配置,启动mysql
c.此时可以回车使用空密码正常登录,然后再使用alter user等语句修改密码即可。
4.修改密码完成后关掉使用--skip-grant-tables启动的mysql,然后重启mysql服务,之后就可以使用新密码登录了。
```
## 三、权限管理
```
权限管理主要是对登录到MySQL的用户进行权限验证。所有用户的权限都存储在MySQL的权限表中,不合理的权限规划会给MySQL带来安全隐患。
MySQL权限系统的主要功能是证实连接到一台给定主机的用户,并且赋予该用户在数据库上的select、insert、update和delete权限。
```
### 3.1 MySQL的各种权限
```
账户信息被储存在MySQL数据库的 user、db、host、tables_priv、columns_priv和procs_priv表中。
在MySQL启动时,服务器将这些数据库表中权限信息的内容读入内存。
```
#### 3.1.1 grant和revoke语句涉及的权限的名称如下所示:
```
(1)create 和 drop权限,可以创建新数据库和表,或删除已有数据库和表;
(2)select、insert、update和delete权限允许在一个数据库`现有`的表上实施操作;
(3)index 权限允许创建或删除索引,index适用已有表。如果具有某个表的create权限,可以在create table语句中包括索引定义。
(4)alter 权限,可以使用alter table来更改表的结构和重新命名表。
(5)create routine 权限来创建保存的程序(函数和程序),alter routine权限来更改和删除保存的程序,execute权限用来执行保存的程序。
(6)grant 权限允许授权给其他用户。可用于数据库、表和保存的程序。
(7)file 权限给予用户使用load data infile和select...into outfile语句读或写服务器上的文件,任何被授予file权限的用户都能都或者写mysql服务器上的任何文件。
file权限允许用户在MySQL服务器具有写权限的目录下创建新文件,但不能覆盖已有文件。
```
### 3.2 授权
```
授权就是为某个用户授予权限,MySQL中使用grant语句为用户授予权限。
授予的权限可以分为多个层级:
1.全局级
全局权限适用于一个给定服务器中的所有数据库。这些权限存储在mysql.user表中。
grant all on *.* 授权全局权限
revoke all on *.* 撤销全局权限
2.数据库层级
数据库权限适用于一个给定数据库中的所有目标。这些权限存储在mysql.db表和mysql.host表中。
grant all on db_name.* 授予数据库权限
revoke all on db_name.* 撤销数据库权限
3.表层级
表权限适用于一个给定表中的所有列。这些权限存储在mysql.tables_priv表中。
grant all on db_name.table_name 授权表权限
revoke all on db_name.table_name 撤销表权限
4.列层级
列权限适用于一个给定表中的单列。这些权限存储在mysql.columns表中。
当使用revoke时,必须指定与被授权列相同的列。
5.子程序层级
注意:每个层级的权限互不包含,需要逐项查看。
```
#### 3.2.1 全局层级
```
全局权限适用于一个给定服务器中的所有数据库,这些权限存储在mysql.user表中。
操作对象:给定服务器中的所有数据库
权限存储:mysql.user表
授予全局权限:grant all on *.*
撤销全局权限:revoke all on *.*
说明:
*.* 第一个*表示数据库,第二个*表示对象(表、视图等);
*.* 表示所有库的所有对象(表、视图等)。
此时授予/撤销的权限不包括 grant option 权限,
而 grant option 权限只能通过'with grant option'的方式被授予。
```
```
2.范例:
1.给用户cui授予全局层级权限select
mysql> grant select on *.* to 'cui'@'%';
mysql> flush privileges;
2.查看用户cui的全局级权限信息
mysql> select * from mysql.user where user = 'cui'\G
*************************** 1. row ***************************
Host: %
User: cui
Select_priv: Y
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
Process_priv: N
File_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Show_db_priv: N
Super_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Execute_priv: N
Repl_slave_priv: N
Repl_client_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Create_user_priv: N
Event_priv: N
Trigger_priv: N
Create_tablespace_priv: N
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin: mysql_native_password
authentication_string: *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9
password_expired: N
password_last_changed: 2023-01-10 09:39:54
password_lifetime: NULL
account_locked: N
1 row in set (0.00 sec)
```
#### 3.2.2 数据库层级
```
数据库权限适用于一个给定数据库中的所有目标,这些权限存储在mysql.db和mysql.host表中。
操作对象:给定数据库
权限存储:mysql.db表
只授予数据库权限:grant all on db_name.*
只撤销数据库权限:revoke all on db_name.*
说明:
db_name.* 表示哪个数据库的所有表,即整个库;
例如:mysql.* 即mysql库的所有表,即mysql库。
范例:
1.创建用户cui
mysql> create user 'cui'@'%' identified by '123';
2.给用户cui对mysql库授予select权限
mysql> grant select on mysql.* to 'cui'@'%';
mysql> flush privileges;
3.查看用户cui的数据库层级权限信息
mysql> select * from mysql.db where user='cui'\G
*************************** 1. row ***************************
Host: %
Db: mysql
User: cui
Select_priv: Y
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Execute_priv: N
Event_priv: N
Trigger_priv: N
1 row in set (0.00 sec)
```
#### 3.2.3 表层级
```
表权限适用于一个给定表中的所有列,这些权限存储在mysql.tables_priv表中。
操作对象:给定的表
权限存储:mysql.tables_priv表
只授权表权限:grant all on db_name.tbl_name
只回撤销权限:revoke all on db_name.tbl_name
范例:
1.创建用户cui
mysql> create user 'cui'@'%' identified by '123';
2.给用户cui对mysql库的user表授予select权限
mysql> grant select on mysql.user to 'cui'@'%';
mysql> flush privileges;
3.查看用户cui的表层级权限信息
mysql> select * from mysql.tables_priv where user='cui'\G
*************************** 1. row ***************************
Host: %
Db: mysql
User: cui
Table_name: user
Grantor: root@localhost
Timestamp: 0000-00-00 00:00:00
Table_priv: Select
Column_priv:
1 row in set (0.00 sec)
```
#### 3.2.4 列层级
```
列权限适用于一个给定表的所有列,这些权限存储在mysql.columns_priv表中。
当使用revoke时必须指定与被授权列相同的列。
操作对象:给定表的列
权限存储:mysql.columns_priv表
1.语法:
grant priv_type(columns1,columns2...) on table1,table2,...,tablen to 'user'@'host';
2.范例:
1.给用户cui授予对mysql库的user表的user列和host列有select权限。
mysql> grant select(user,host) on mysql.user to 'cui'@'%';
mysql> flush privileges;
2.查看用户cui的列层级权限信息
mysql> select * from mysql.columns_priv where user = 'cui'\G
*************************** 1. row ***************************
Host: %
Db: mysql
User: cui
Table_name: user
Column_name: user
Timestamp: 0000-00-00 00:00:00
Column_priv: Select
*************************** 2. row ***************************
Host: %
Db: mysql
User: cui
Table_name: user
Column_name: host
Timestamp: 0000-00-00 00:00:00
Column_priv: Select
2 rows in set (0.00 sec)
```
#### 3.2.5 子程序层级
```
create routine、alter routine、execute和grant权限适用于已存储的子程序。这些权限可以被授权为全局层级和数据库层级。
而且除了create routine外,这些权限可以被授予子程序层级,并存储在mysql.proce_priv表中。
```
#### 3.2.6 grant
```
要使用grant或revoke,必须拥有 grant option 权限,并且必须用于正在授权或撤销的权限。
grant的语法如下:
GRANT priv_type [ (columns) ] [, priv_type [ (columns) ] ] ...
ON [object_type] table1,table2,...,tablen
TO user [ IDENTIFIEDN BY [PASSWORD] 'password' ] [, user [ IDENTIFIEDN BY [PASSWORD] 'password' ] ] ... [ WITH GRANT OPTION ]
参数:
priv_type 表示权限类型。
columns 表示权限作用于哪些列上,不指定该参数则表示作用于整个表。
object_type 表示授权作用的对象类型包括TABLE(表)、FUNCTION (函数)和PROCEDURE(存储过程)。
table1,table2,...,tablen 表示授予权限的列所在的表。
use 表示用户账户,由用户名和主机名组成,形式是‘username@hostname’
IDENTIFIEDN BY 用于设置密码。
WITH 关键字后面可以跟一个或多个GRANT OPTION,GRANT OPTION的取值有5个,意义如下:
(1)GRANT OPTION:表示允许用户将自己的权限授权给其它用户(即该用户有使用grant语句给其他用户授权的权限,不加则该用户不可使用grant语句)。
(2)MAX_QUERIES_PER_HOUR count:设置每小时可以执行count次查询。
(3)MAX_UPDATES_PER_HOUR count:设置每小时可以执行count次更新。
(4)MAX_CONNECTIONS_PER_HOUR count:设置每小时可以建立count个连接。
(5)MAX_USER_CONNECTIONS count:设置单个用户可以同时建立count个连接。
```
#### 3.2.7 grant权限补充
```
在MySQL中只有具有 grant 权限的用户才可以执行grant语句。
例如:当一个普通用户被root用户授予了grant权限后,则该用户可以将自己拥有的权限(包括grant权限)授予其他用户。
【以下为自己理解】
1. 授予grant权限:
grant权限只能通过'with grant option'的方式被授予。
2. 撤销grant权限:
通过revoke grant option on mysql.* from 'user'@'host';的方式被取消,其中的权限层级要根据实际情况进行修改。
```
```
1. 范例:
<1>. 给用户cxb授予对mysql库有select,update和insert权限,且授予grant权限。
mysql> grant select,update,insert on mysql.* to 'cxb'@'%' with grant option;
mysql> flush privileges;
<2>. 在mysql.db表中查看用户cxb的权限信息。
mysql> select * from mysql.db where user = 'cxb'\G
*************************** 1. row ***************************
Host: %
Db: mysql
User: cxb
Select_priv: Y
Insert_priv: Y
Update_priv: Y
Delete_priv: N
Create_priv: N
Drop_priv: N
Grant_priv: Y
References_priv: N
Index_priv: N
Alter_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Execute_priv: N
Event_priv: N
Trigger_priv: N
1 row in set (0.00 sec)
<3>. 撤销用户cxb的grant权限。
mysql> revoke grant option on mysql.* from 'cxb'@'%';
<4>. 查看用户cxb的权限(发现已经没有了grant权限了)。
mysql> show grants for 'cxb'@'%';
+------------------------------------------------+
| Grants for cxb@% |
+------------------------------------------------+
| GRANT USAGE ON *.* TO 'cxb'@'%' |
| GRANT INSERT, UPDATE ON `mysql`.* TO 'cxb'@'%' |
+------------------------------------------------+
2 rows in set (0.00 sec)
```
### 3.3 收回权限
```
revoke [rɪˈvoʊk] v.撤销
收回权限就是取消已经赋予用户的某些权限,MySQL中使用revoke语句取消用户权限。
```
#### 3.3.1. 语法
```
语法一:用于收回已命名用户的所有全局层级、数据库层级、表层级和列层级的权限。
revoke all privileges,grant option from 'user'@'host' [,'user'@'host' ...];
语法二:用于收回用户的指定权限。
revoke priv_type on tablel,table2,...,tablen from 'user'@'host' [,'user'@'host' ...];
说明:
revoke语句必须和from语句一起使用,from语句指明需要收回权限的用户。
要使用revoke语句,必须拥有mysql数据库的全局create user权限或update权限。
```
#### 3.3.2. 范例
```
范例1、使用revoke语句收回grantuser用户的更新权限。
mysql> revoke update on *.* from 'grantuser'@'%';
```
### 3.4 查看权限
```
语法一:查看指定用户的权限
show grants for 'user'@'host';
语法二:查看当前用户的权限
show grants;
```
## 四、MySQL角色模拟
```
角色(Role)可以用来批量管理用户,同一个角色下的用户,拥有相同的权限。
MySQL5.7.X以后可以模拟角色(Role)的功能,通过mysql.proxies_priv模拟实现。
mysql.proxies_priv在5.5.X和5.6.X的时候就存在,但是无法模拟角色(Role)功能。
```
### 4.1 模拟角色操作
```
1. 创建一个角色(dba)
mysql> create user 'dba'@'localhost';
2. 给创建好的角色赋予权限
mysql> grant select on sys.* to 'dba'@'localhost';
3. 创建两个用户
mysql> create user 'test01'@'%' identified by '123';
mysql> create user 'test02'@'%' identified by '123';
4. 将dba角色映射到两个用户
mysql> grant proxy on 'dba'@'localhost' to 'test1'@'%';
mysql> grant proxy on 'dba'@'localhost' to 'test2'@'%';
mysql> flush privileges;
5. 查看用户的权限
mysql> show grants for 'test01'@'%';
+-------------------------------------------------+
| Grants for test01@% |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO 'test01'@'%' |
| GRANT PROXY ON 'dba'@'localhost' TO 'test01'@'%' |
+-------------------------------------------------+
2 rows in set (0.00 sec)
6. 查看mysql.proxies_priv表
mysql> select * from mysql.proxies_priv;
+-----------+-------+--------------+--------------+------------+--------- -------------+---------------------+
| Host | User | Proxied_host | Proxied_user | With_grant | Grantor | Timestamp |
+-----------+-------+--------------+--------------+------------+--------- -------------+---------------------+
| localhost | root | | | 1 | boot@connecting host | 0000-00-00 00:00:00 |
| % | test01 | localhost | dba | 0 | root@localhost | 0000-00-00 00:00:00 |
| % | test02 | localhost | dba | 0 | root@localhost | 0000-00-00 00:00:00 |
+-----------+-------+--------------+--------------+------------+--------- -------------+---------------------+
3 rows in set (0.00 sec)
```




