文章目录
前言
在学习Linux命令行操作的时候,我们就能够理解root用户和普通用户的区别,那么mysql中是否也存在这样的差别呢?答案是肯定的。本栏目中,《用户管理》前的所有章节,我们都是以root用户进行演示的,而在实际业务场景下,我们使用更多的是普通用户,因为root用户权限太大了。随意将root用户给他人使用,存在严重的安全隐患。因此,MySQL的用户管理相关功能是必不可少的。

一、用户管理操作
本小节主要讲解mysql提供的对用户进行CRUD操作的指令。
1.1、用户信息查看
我们通过show databases指令,可以查看到MySQL默认为我们提供的一个数据库mysql,打开该数据库,可以发现其中包含一个user表。从表名我们就能够看出,这个就是用于保存MySQL的用户的信息的一张表。"mysql一切皆表"

使用查询语句 select * from user \G 观察此表,我们应该可以看到有多个用户,其中有一些是系统默认创建的,我们不用在意,我们现在只看root用户相关内容。
字段解释:
host:表示这个用户可以从哪个主机登陆。如果是localhost,表示只能从本机登陆user:用户名authentication_string:用户密码通过password函数加密后的*_priv:用户拥有的权限

从上图可以看出,我们所关注的关键字段就只有两个User和Host,因此,我们仅显示这两个字段来查看用户信息,这也是我们比较常用的操作。
sql
mysql> select User, Host from user;
+------------------+-----------+
| User | Host |
+------------------+-----------+
| debian-sys-maint | localhost |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)
1.2、创建用户
语法🐬:
create user '用户名'@'登录主机/ip地址' identified by '密码'
此处的用户名与登录主机,就是用于填充user表中的User和Host字段的。在用户管理中,我们常常将这两个字段绑定作为一个整体 。

示例:创建一个用户,用户名为zhangsan,登录主机为localhost,密码为123456
sql
-- 此处的localhost,修改为127.0.0.1,效果完全一样
mysql> create user 'zhangsan'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.07 sec)
mysql> select User, Host from user;
+------------------+-----------+
| User | Host |
+------------------+-----------+
| debian-sys-maint | localhost |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| zhangsan | localhost |
-- 新增的用户,此时,我们便可以利用zhangsan的身份进行登录了
+------------------+-----------+
6 rows in set (0.00 sec)
这时有些人会思考一个问题:既然用户本质就是user表里面的一行数据,那么我们为什么直接使用insert语句对该表进行插入操作呢🤔??
理论上,完全可以这样子操作。但是,
user表中的字段并不仅仅包含User和Host字段,它还包含许多的权限设置,如果要使用insert插入数据,那一定极其麻烦的。此外既然已经有了专门的创建用户的语句,为什么还要使用insert呢!
此外,我们目前基本上都是使用云服务器进行学习的,因此,我们的mysqld处于公网环境下。而我们使用的windows主机基本上都是处于内网环境。可能有同学会尝试用自己的windows主机上的IP地址在云服务器上的mysql的user表中创建一个新用户,然后在本地的mysql客户端进行远程连接,最终的结果往往是失败。这里就牵扯到了网络相关知识------NAT技术 。在内网中,我们发送的报文的源地址会最终替换为出入口路由器(连接公网和内网的路由器)的WAN口IP 。因此,最终到达我们云服务器的源IP地址,不是我们一开始设定的IP地址,自然便访问失败(有关NAT技术更加详细的解说,此处不再展开)。那么我们应该如何在本地windows系统上远程连接云服务器上的mysql服务呢🤔??
我们在创建新用户的时候,可以将IP地址填写为
%。它表示的是:允许用户从任何主机访问数据库服务器。我们创建'lisi'@'%'为例。
sqlmysql> create user 'lisi'@'%' identified by '123456'; Query OK, 0 rows affected (0.02 sec) mysql> select User,Host from user; +------------------+-----------+ | User | Host | +------------------+-----------+ | lisi | % | | debian-sys-maint | localhost | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | | zhangsan | localhost | +------------------+-----------+ 7 rows in set (0.00 sec)此时,我们便可以从windows主机上远程访问mysql服务了。
不过,我们极其不建议这样子做,任何主机都能够访问该用户的数据库,这绝对会埋下重大的安全隐患。因此,在实际业务中,我们绝对不会将mysql的端口暴露到公网。不过我们目前在学习阶段,数据库中也不会存储什么重要的内容,如果需要远程访问,也只能够采取这样的方法。
一般,互联网公司是如何解决这个问题的呢??
互联网公司内部都是有自己的内网的,在同一个内网内,并不会引发我们之前所谈到的问题。因此不必担心,可以放心地进行远程访问。
1.3、删除用户
语法🐬:
drop user '用户名'@'IP地址'
示例:删除'lisi'@'%'
sql
mysql> drop user 'lisi'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> select User,Host from user;
+------------------+-----------+
| User | Host |
+------------------+-----------+
| debian-sys-maint | localhost |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| zhangsan | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
1.4、修改用户密码
修改用户密码的操作,可以分为两种情况:
- 自己修改自己的密码
- root用户修改指定用户的密码(root用户拥有最高权限,管理普通用户)
语法🐬:
set password=password('new_password')(自己修改自己的密码)
set password for '用户名'@'IP地址'=password('new_password')(root修改指定用户的密码)
示例1️⃣:'zhangsan'@'localhost'修改自己的密码
sql
-- 原密码为123456,修改为654321
mysql> select user();
+--------------------+
| user() |
+--------------------+
| zhangsan@localhost |
+--------------------+
1 row in set (0.00 sec)
mysql> set password=password('654321');
-- 修改后尝试使用new_password登录,登陆成功
示例2️⃣:root修改'zhangsan'@'localhost'的密码
sql
mysql> set password for 'zhangsan'@'localhost'=password('123456');
由于MySQL 8.0后已经废除了password()函数,因此,语法格式上也会有略微修改。以上的语法格式仅适用MySQL 5.7(市面上较常用的一个版本)。
MySQL 8.0后,要修改用户密码,只需要在我们之前语法格式的基础上,将password()函数去掉即可,只保留明文部分,MySQL内部会自主进行加密处理。
示例1️⃣:'zhangsan'@'localhost'修改自己的密码
sql
-- 原密码为123456,修改为654321
mysql> select user();
+--------------------+
| user() |
+--------------------+
| zhangsan@localhost |
+--------------------+
1 row in set (0.00 sec)
mysql> set password='654321';
Query OK, 0 rows affected (0.03 sec)
-- 修改后尝试使用new_password登录,登陆成功
示例2️⃣:root修改'zhangsan'@'localhost'的密码
sql
mysql> set password for 'zhangsan'@'localhost'='123456';
Query OK, 0 rows affected (0.01 sec)
其实还有一个更加通用的写法:
alter user '用户名'@'IP地址' identified by 'new_password';
sql
mysql> alter user 'zhangsan'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> select User,Host,authentication_string from user;
+------------------+-----------+------------------------------------------------------------------------+
| User | Host | authentication_string |
+------------------+-----------+------------------------------------------------------------------------+
| debian-sys-maint | localhost | $A$005$9%g(n NN:"D<TW.K)%0hjn7BZOeL/iPDGm4g2lqTVWjs1DpbmzuMQZtH0VdYKA |
| mysql.infoschema | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.session | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.sys | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| root | localhost | *96CA658E7C485D73DE56C62591F667CDCE8966EA |
| zhangsan | localhost | $A$005$viYQkFOCagZ1+8:or5jNs4rhSuiaB9wU8yaVFYSvDo0jBhvGpvZDkUiTZ66jC |
+------------------+-----------+------------------------------------------------------------------------+
6 rows in set (0.00 sec)
每次修改完密码或者用户权限的时候,我们要么将客户端重启,要么就使用指令flush privileges来刷新配置。
二、数据库权限管理
讲完了用户的CRUD操作后,我们来讲讲MySQL的权限管理。
MySQL数据库提供的权限列表:

2.1、授权操作
对于新创建的用户来说,是没有任何权限的,因此需要给用户授权。
语法🐬:
grant 权限列表 on 库.表名 to '用户名'@'IP地址'
说明:
-
权限列表,多个权限使用逗号隔开
grant select on ...grant select, delete, create on ...grant all [privileges] on ... -
库.表名,当使用
*.*时,代表本系统中的所有数据库的所有对象(表、视图、存储过程等);当使用库.*时,代表本系统中的对应数据库的所有对象
- 只有附上对应的权限,用户才可以看到对应数据库上的表。
- 取消用户对应的数据库的表的所有权限,这个表对用户来说,就是不可见的。
- 如果用户对某数据的所有表都没有权限,那么,这个数据库对用户来说,就是不可见的。
未来,我们建议使用root用户新建普通用户后,root统一建好数据库和表结构,然后再根据用户的职能来定制化地赋权。
2.2、回收权限
语法🐬:
revoke 权限列表 on 库.表名 to '用户名'@'IP地址'
完🎇🎇🎇