用户管理

登录MySQL服务器

查询用户

在mysql数据库中查询用户表

  1. use mysql;
  2. select Host,User from user;

MySQL用户与权限 - 图1

显示了mysql自带的用户

创建用户

基本语法:

  1. CREATE USER 用户名 [IDENTIFIED BY '密码'][,用户名 [IDENTIFIED BY '密码']];
  • 用户名参数表示新建用户的账户,由 用户(User) 和 主机名(Host) 构成;
  • “[ ]”表示可选,也就是说,可以指定用户登录时需要密码验证,也可以不指定密码验证,这样用户可以直接登录。不过,不指定密码的方式不安全,不推荐使用。如果指定密码值,这里需要使用
  • IDENTIFIED BY指定明文密码值。
  • CREATE USER语句可以同时创建多个用户。

此时创建zhangsan用户

  1. create user 'zhangsan' IDENTIFIED BY '123'; # 默认host是 %

MySQL用户与权限 - 图2

此时用户等登录的端口号默认为%

此时再次创建zhangsan,指明端口号为localhost

  1. create user 'zhangsan'@'localhost' INENTIFIED 123;

MySQL用户与权限 - 图3

注意:此处的user的主键是Host和User组成的复合主键。因此端口号不同,用户名相同也可以添加。

修改用户

即直接对user表,修改用户名和端口号等等

修改zhangsan为lisi

  1. update user set User = 'lisi' where User = 'zhangsan';

MySQL用户与权限 - 图4

注意此时需要刷新权限才可以登录

  1. FLUSH PRIVILEGES;

删除用户

  • 方式一:使用drop(推荐)
    使用DROP USER语句来删除用户时,必须用于DROP USER权限。DROP USER语句的基本语法形式如下:
    删除lisi,此时删除host为%的lisi用户
    MySQL用户与权限 - 图5
    将host为localhost用户删除
    MySQL用户与权限 - 图6

    1. DROP USER user[,user]…; # 默认删除host为%的用户
  • 方式二:使用DELETE方式删除(不推荐)
    删除完成后需要刷新权限

    1. DELETE FROM user WHERE Host=’hostname AND User=’username’;
    1. FLUSH PRIVILEGES;

注意:不推荐通过 DELETE FROM USER u WHERE USER=’li4’ 进行删除,系统会有残留信息保留。而drop user命令会删除用户以及对应的权限,执行命令后你会发现mysql.user表和mysql.db表的相应记录都消失了。

设置当前用户密码

  • 方式一:使用ALTER USER命令来修改当前用户密码用户可以使用ALTER命令来修改自身密码,如下语句代表修改当前登录用户的密码。基本语法如下:

    1. ALTER USER USER() IDENTIFIED BY 'new_password';
  • 方式二:使用SET语句来修改当前用户密码** 使用root用户登录MySQL后,可以使用SET语句来修改密码,具体SQL语句如下:
    该语句会自动将密码加密后再赋给当前用户。

    1. SET PASSWORD='new_password';

设置其他用户密码

  • 方式一:使用ALTER语句来修改普通用户的密码可以使用ALTER USER语句来修改普通用户的密码。基本语法形式如下:

    1. ALTER USER '用户名' [IDENTIFIED BY '新密码'] [,user[IDENTIFIED BY '新密码']]…;
  • 方式二:使用SET命令来修改普通用户的密码使用root用户登录到MySQL服务器后,可以使用SET语句来修改普通用户的密码。SET语句的代码如下:

    1. SET PASSWORD FOR '用户名'@'hostname'='new_password';
  • 方式三:使用UPDATE语句修改普通用户的密码(不推荐)

    1. UPDATE MySQL.user SET authentication_string=PASSWORD("123456") WHERE User = "用户名" AND Host = "hostname";

注意:设置完成后需要刷新权限才可生效。

权限管理

权限列表

  1. SHOW PRIVILEGES;

(1) CREATE和DROP权限 ,可以创建新的数据库和表,或删除(移掉)已有的数据库和表。如果将MySQL数据库中的DROP权限授予某用户,用户就可以删除MySQL访问权限保存的数据库。

(2) SELECT、INSERT、UPDATE和DELETE权限 允许在一个数据库现有的表上实施操作。

(3) SELECT权限只有在它们真正从一个表中检索行时才被用到。

(4) INDEX权限 允许创建或删除索引,INDEX适用于已有的表。如果具有某个表的CREATE权限,就可以在CREATE TABLE语句中包括索引定义。

(5) ALTER权限 可以使用ALTER TABLE来更改表的结构和重新命名表。

(6) CREATE ROUTINE权限 用来创建保存的程序(函数和程序),ALTER ROUTINE权限用来更改和删除保存的程序, EXECUTE权限 用来执行保存的程序。

(7) GRANT权限 允许授权给其他用户,可用于数据库、表和保存的程序。

(8) FILE权限 使用户可以使用LOAD DATA INFILE和SELECT … INTO OUTFILE语句读或写服务器上的文件,任何被授予FILE权限的用户都能读或写MySQL服务器上的任何文件(说明用户可以读任何数据库目录下的文件,因为服务器可以访问这些文件)

授予权限

  1. GRANT 权限1,权限2,…权限n ON 数据库名称.表名称 TO 用户名@用户地址 [IDENTIFIED BY ‘密码口令’];

该权限如果发现没有该用户,则会直接新建一个用户。使用 * 可以代表所有数据库或者所有数据表

例:

给zhangsan用户mytest1数据库所有表的查询和更新权限

  1. grant select,update on mytest1.* to 'zhangsan'@'%';

授予通过网络方式登录的zhangsan用户 ,对所有库所有表的全部权限,密码设为123。注意这里唯独不包括grant的权限(就是不能给其他用户赋权限)

  1. grant all privileges on *.* to 'zhangsan'@'%';

我们在开发应用的时候,经常会遇到一种需求,就是要根据用户的不同,对数据进行横向和纵向的分组。

  • 所谓横向的分组,就是指用户可以接触到的数据的范围,比如可以看到哪些表的数据;
  • 所谓纵向的分组,就是指用户对接触到的数据能访问到什么程度,比如能看、能改,甚至是删除。

查看权限

  • 查看当前用户权限

    1. SHOW GRANTS;
    2. # 或
    3. SHOW GRANTS FOR CURRENT_USER;
    4. # 或
    5. SHOW GRANTS FOR CURRENT_USER();
  • 查询某用户的全局权限

    1. SHOW GRANTS FOR '用户名'@'主机地址' ;

收回权限

收回权限就是取消已经赋予用户的某些权限。收回用户不必要的权限可以在一定程度上保证系统的安全性。MySQL中使用 REVOKE语句 取消用户的某些权限。使用REVOKE收回权限之后,用户账户的记录将从db、host、tables_priv和columns_priv表中删除,但是用户账户记录仍然在user表中保存(删除user表中的账户记录使用DROP USER语句)。

  1. REVOKE 权限1,权限2,…权限n ON 数据库名称.表名称 FROM 用户名@用户地址;

收回zhangsan的所有权限,此时提示需要SYSTEM_USER权限,需要root给自己赋SYSTEM_USER权限

MySQL用户与权限 - 图7

注意:须用户重新登录后才能生效

权限表

user表

user表是MySQL中最重要的一个权限表, 记录用户账号和权限信息 ,有49个字段。

  1. user mysql;
  2. DESC user; # 查询user表的字段啊

这些字段可以分成4类,分别是范围列(或用户列)、权限列、安全列和资源控制列。

范围列(或用户列)

  • host : 表示连接类型
    • % 表示所有远程通过 TCP方式的连接
    • IP 地址 如 (192.168.1.2、127.0.0.1) 通过制定ip地址进行的TCP方式的连接
    • 机器名 通过制定网络中的机器名进行的TCP方式的连接
    • ::1 IPv6的本地ip地址,等同于IPv4的 127.0.0.1 localhost 本地方式通过命令行方式的连接 ,比如mysql -u xxx -p xxx 方式的连接。
  • user : 表示用户名,同一用户通过不同方式链接的权限是不一样的。
  • password :
    • 密码所有密码串通过 password(明文字符串) 生成的密文字符串。MySQL 8.0 在用户管理方面增加了角色管理,默认的密码加密方式也做了调整,由之前的 SHA1 改为了 SHA2 ,不可逆 。同时加上 MySQL 5.7 的禁用用户和用户过期的功能,MySQL 在用户管理方面的功能和安全性都较之前版本大大的增强了。
    • mysql 5.7 及之后版本的密码保存到 authentication_string 字段中不再使用password 字段。

权限列

  • Grant_priv字段
    • 表示是否拥有GRANT权限
  • Shutdown_priv字段
    • 表示是否拥有停止MySQL服务的权限
  • Super_priv字段
    • 表示是否拥有超级权限
  • Execute_priv字段
    • 表示是否拥有EXECUTE权限。拥有EXECUTE权限,可以执行存储过程和函数。
  • Select_priv , Insert_priv等
    • 为该用户所拥有的权限

安全列

安全列只有6个字段,其中两个是ssl相关的(ssl_type、ssl_cipher),用于 加密 ;两个是x509相关的(x509_issuer、x509_subject),用于 标识用户 ;另外两个Plugin字段用于 验证用户身份 的插件,该字段不能为空。如果该字段为空,服务器就使用内建授权验证机制验证用户身份。

资源控制列

资源控制列的字段用来 限制用户使用的资源 ,包含4个字段,分别为:

  • max_questions,用户每小时允许执行的查询操作次数;
  • max_updates,用户每小时允许执行的更新操作次数;
  • max_connections,用户每小时允许执行的连接操作次数;
  • max_user_connections,用户允许同时建立的连接次数。

db表

  1. DESCRIBE mysql.db; # 查看db表
  • 用户列
    db表用户列有3个字段,分别是Host、User、Db。这3个字段分别表示主机名、用户名和数据库名。表示从某个主机连接某个用户对某个数据库的操作权限,这3个字段的组合构成了db表的主键。MySQL用户与权限 - 图8
  • 权限列
    Create_routine_priv和Alter_routine_priv这两个字段决定用户是否具有创建和修改存储过程的权限。

tables_priv表和columns_priv表

tables_priv表用来 对表设置操作权限 ,columns_priv表用来对表的 某一列设置权限 。tables_priv表和columns_priv表的结构分别如图:

tables_priv表有8个字段,分别是Host、Db、User、Table_name、Grantor、Timestamp、Table_priv和 Column_priv,各个字段说明如下:

  • Host 、 Db 、 User 和 Table_name 四个字段分别表示主机名、数据库名、用户名和表名。
  • Grantor表示修改该记录的用户。
  • Timestamp表示修改该记录的时间。
  • Table_priv 表示对象的操作权限。包括Select、Insert、Update、Delete、Create、Drop、Grant、
  • References、Index和Alter。
  • Column_priv字段表示对表中的列的操作权限,包括Select、Insert、Update和References

procs_priv表

procs_priv表可以对 存储过程和存储函数设置操作权限 ,表结构如图:

  1. desc pross_priv;

MySQL用户与权限 - 图9

角色管理

引入角色的目的是 方便管理拥有相同权限的用户 。恰当的权限设定,可以确保数据的安全性,这是至关重要的

MySQL用户与权限 - 图10

创建角色

语法格式:

  1. CREATE ROLE 'role_name'[@'host_name'] [,'role_name'[@'host_name']]...

角色名称的命名规则和用户名类似。如果 host_name省略,默认为% , role_name不可省略 ,不可为

空。

例如:

创建经理角色

  1. create role 'manager'@'%';

给角色赋予权限

创建角色之后,默认这个角色是没有任何权限的,我们需要给角色授权。给角色授权的语法结构是:

  1. GRANT privileges ON table_name TO 'role_name'[@'host_name'];

上述语句中privileges代表权限的名称,多个权限以逗号隔开。可使用SHOW语句查询权限名称,图11-43列出了部分权限列表。

例如:

给经理角色赋予查询所有库的所有表查询权限

  1. grant select on *.* to 'manager'@'%';

查看角色的权限

赋予角色权限之后,我们可以通过 SHOW GRANTS 语句,来查看权限是否创建成功了:

  1. show grants for '角色名';

MySQL用户与权限 - 图11

只要你创建了一个角色,系统就会自动给你一个“ USAGE ”权限,意思是 连接登录数据库的权限 。

回收角色的权限

角色授权后,可以对角色的权限进行维护,对权限进行添加或撤销。添加权限使用GRANT语句,与角色授权相同。撤销角色或角色权限使用REVOKE语句。修改了角色的权限,会影响拥有该角色的账户的权限。

  1. REVOKE privileges ON tablename FROM 'rolename';

例如:回收经理的查询权限

MySQL用户与权限 - 图12

删除角色

当我们需要对业务重新整合的时候,可能就需要对之前创建的角色进行清理,删除一些不会再使用的角色。

  1. DROP ROLE role [,role2]...;

注意, 如果你删除了角色,那么用户也就失去了通过这个角色所获得的所有权限 。

给用户赋予角色

角色创建并授权后,要赋给用户并处于 激活状态 才能发挥作用。给用户添加角色可使用GRANT语句,语法形式如下:

  1. GRANT role [,role2,...] TO user [,user2,...];

例如:给zhangsan赋予manager角色

MySQL用户与权限 - 图13

此时使用zhangsan登录,查看此时角色

MySQL用户与权限 - 图14

此时角色未激活,无法使用。

激活角色

  1. SET DEFAULT ROLE ALL TO 'zhangsan'@'%';

例如:给zhangsan激活manager角色

MySQL用户与权限 - 图15

此时可以查询到角色信息

MySQL用户与权限 - 图16

设置自动激活角色

将activate_all_roles_on_login设置为ON

默认情况:

  1. show variables like 'activate_all_roles_on_login';

MySQL用户与权限 - 图17

设置:

  1. SET GLOBAL activate_all_roles_on_login=ON;

这条 SQL 语句的意思是,对 所有角色永久激活 。运行这条语句之后,用户才真正拥有了赋予角色的所有权限。

撤销用户的角色

撤销用户角色的SQL语法如下:

  1. REVOKE role FROM user;

MySQL用户与权限 - 图18

设置强制角色(mandatory role)

方式1:服务启动前设置

  1. [mysqld]
  2. mandatory_roles='role1,role2@localhost,r3@%.atguigu.com'

方式2:运行时设置

  1. SET PERSIST mandatory_roles = 'role1,role2@localhost,r3@%.example.com';
  2. #系统重启后仍然 有效
  3. SET GLOBAL mandatory_roles = 'role1,role2@localhost,r3@%.example.com';
  4. #系统重启后失效