用户和权限管理
应用场景数据库服务安装成功后默认有一个 root 用户,可以新建和操纵数据库服务中管理的所有数据库。在真实的使用过程中,通常每个应用对应着一个数据库,我们只希望某个用户只能操纵和管理当前应用对应的那个数据库,而不能操纵和管理其他应用的数据库,这时就可以添加一个用户并指定用户的权限

如上图所示:
-
root 可以访问和操纵所有的数据库:DB1, DB2, DB3, DB4
-
普通用户 1 只能访问和操纵数据库 DB1
-
普通用户 2 只能访问和操纵数据库 DB3
-
只读用户 1 只能访问数据库 DB3
-
只读用户 2 只能访问数据库 DB4
用户
3.1 查看用户
MySQL 的用户信息保存在 mysql 系统数据库的 user 表中,可以通过 Select 语句查看,如下所示:
# 选择数据库
mysql> use mysql
Database changed
# 查看所有的表
mysql> show tables;
# 查看表结构
mysql> desc user;
# 查询user表中的记录
mysql> select host, user, authentication_string from user;
+------------------+------------------+------------------------------------------------------------------------+
| host | user | authentication_string |
+------------------+------------------+------------------------------------------------------------------------+
| localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root | $A$005$4*/zI3, S2!90SH5k8QgT2Bo6ePFBOP6cbLlgLXQTasCSS8WzBDdXrC |
+------------------+------------------+------------------------------------------------------------------------+
4 rows in set (0.00 sec)
-
host: 允许登录的主机,相当于白名单,如果是localhost,表示只能从本机登陆
-
user: 用户名
-
*_priv: 用户拥有的权限
-
authentication_string: 加密后的用户密码
desc user; -

注意:
select * from user\G;

3.2 创建用户
3.2.1 语法
CREATE USER [IF NOT EXISTS] 'user_name'@'host_name' IDENTIFIED BY 'auth_string';
user_name: 用户名,用单引号包裹,区分大小写host_name: 主机或 IP (段),用单引号包裹auth_string: 真实密码,有密码策略不允许使用简单密码
3.2.2 注意事项
- 如果不指定host_name 相当于 'user_name'@'%' ,% 表示所有主机都可以连接到数据库,强烈建议不要这样设置,因为会导致严重的安全问题
- user_name 和 host_name 分别用单引号包裹,如果写成 'user_name@host_name',相当于 'user_name@host_name'@'%'
- host_name 可以通过子网掩码设置主机范围
- 198.0.0.0/255.0.0.0: A 段网络中的任意一台主机
- 198.51.0.0/255.255.0.0: 198.51 B 段网络中的任意一台主机
- 198.51.100.0/255.255.255.0: 198.51.100 C 段网络中的任意一台主机
- 198.51.100.1: 只包含特定 IP 地址的主机
- 从 MySQL 8.0.23 开始,指定为 IPv4 地址的主机值可以使用 CIDR 表示法写入,例如 198.51.100.44/24
- 允许在 IP 地址中使用 % 通配符,比如,主机值 '%' 匹配任何主机名,198.51.100.% 匹配 198.51.100 C 段网络中的任何主机。MySQL 8.0.35 中已弃用,以后可能会删除
3.2.3 示例
# 添加一个名为bit的新用户,允许从本机登录
mysql> create user 'bit'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.02 sec)
# 添加一个名为bit1的新用户,允许从192.168.1.1/24网段登录
mysql> create user 'bit1'@'192.168.1.1/24' identified by '123456';
Query OK, 0 rows affected (0.02 sec)
# 查询,添加成功
mysql> select host, user, authentication_string from user\G
*************************** 1. row ***************************
host: 192.168.1.36/24
user: bit1
authentication_string: LYkbuBpcAPQIf2JJS8cJe4u.5ce6UPmQ0IU2phfmfKQ7-:%
*************************** 2. row ***************************
host: localhost
user: bit
authentication_string: $A$005$P+Pe6Ht 5$SxK0oxjZgt8EUt2nYzalIHaP6f0aSw2BzHeEafnFzB
*************************** 3. row ***************************
host: localhost
user: mysql.infoschema
authentication_string: $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 4. row ***************************
host: localhost
user: mysql.session
authentication_string: $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 5. row ***************************
host: localhost
user: mysql.sys
authentication_string: $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 6. row ***************************
host: localhost
user: root
authentication_string: $A$005$4*/zI3zS2!90SH5k8QgT2Bo6ePFBOP6cbLlgLXQTasCSS8WzBDdXrC
6 rows in set (0.00 sec)
新用户登录
# 使用新用户登录
C:\Users\bit>mysql -ubit -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
3.2.4
3.3 修改密码
3.3.1 语法
# 为指定用户设置密码【推荐】
ALTER USER 'user_name'@'host_name' IDENTIFIED BY 'auth_string';
# 为指定用户设置密码
SET PASSWORD FOR 'user_name'@'host_name' = 'auth_string';
# 为当前登录用户设置密码
SET PASSWORD = 'auth_string';
3.3.2 示例
# 以root身份登录,为'bit'@'localhost'用户重置密码
mysql> ALTER USER 'bit'@'localhost' IDENTIFIED BY '987654';
Query OK, 0 rows affected (0.02 sec)
# 以root身份登录,为'bit'@'localhost'用户重置密码
mysql> SET PASSWORD FOR 'bit'@'localhost' = '123456';
Query OK, 0 rows affected (0.01 sec)
# 以bit用户登录,并确认当前登录用户,USER()与CURRENT_USER()是同义词
mysql> select USER();
+----------------+
| USER() |
+----------------+
| bit@localhost |
+----------------+
1 row in set (0.00 sec)
# 修改当前登录用户的密码
mysql> SET PASSWORD = '111111';
Query OK, 0 rows affected (0.02 sec)
3.4 删除用户
3.4.1 语法
DROP USER [IF EXISTS] 'user_name'@'host_name' [, ...];
[IF EXISTS]:可选参数,表示 "如果用户存在就删除,不存在也不报错"(避免用户不存在时触发错误)。'user_name'@'host_name':必填 ,要删除的用户(user_name)和对应的登录主机(host_name),需用单引号包裹。[, ...]:可选,表示可以同时删除多个用户,用逗号分隔即可。
示例:
-- 同时删除2个用户:hanyulong@localhost、test@192.168.1.1
DROP USER IF EXISTS 'hanyulong'@'localhost', 'test'@'192.168.1.1';
3.4.2 示例
# 删除用户'bit1'@'192.168.1.1/24'
mysql> drop user 'bit1'@'192.168.1.1/24';
Query OK, 0 rows affected (0.01 sec)
# 删除成功,查询用户表确认
mysql> select host, user, authentication_string from user;
+-----------+------------------+------------------------------------------------------------------------+
| host | user | authentication_string |
+-----------+------------------+------------------------------------------------------------------------+
| localhost | bit | $A$005$P+Pe6Ht 5$SxK0oxjZgt8EUt2nYzalIHaP6f0aSw2BzHeEafnFzB |
| localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root | $A$005$4*/zI3zS2!90SH5k8QgT2Bo6ePFBOP6cbLlgLXQTasCSS8WzBDdXrC |
+-----------+------------------+------------------------------------------------------------------------+
5 rows in set (0.00 sec)
权限管理
权限与授权
- MySQL 内置支持的权限列表

1.1 给用户授权
刚创建的用户没有任何权限,需要给他授权,如下所示:
mysql> select user();
+----------------+
| user() |
+----------------+
| bit@localhost |
+----------------+
1 row in set (0.00 sec)
# 看不到其他的数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)
1.1.1 语法
grant priv_type[, priv_type ...] on priv_level
to 'user_name'@'host_name' [WITH GRANT OPTION]
- priv_type:根据类型,参考根据表 4.1 中的 Privilege 列
- priv_level :
*.*|db_name.*|db_name.tbl_name|tbl_name,比如*.*表示所有数据库下的所有表 - 'user_name'@'host_name':指定用户
- [WITH GRANT OPTION]:可选,允许用户将自己的权限授权给其它用户
1.1.2 示例
-
为
bit@localhost用户授权于java01数据库的select权限授权
mysql> grant select on java01.* to 'bit'@'localhost';
Query OK, 0 rows affected (0.04 sec)查看数据库,可以看到java01
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| java01 |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)选择数据库
mysql> use java01
Database changed查看所有表
mysql> show tables;
+-------------------+
| Tables_in_java01 |
+-------------------+
| account |
| class |
| course |
| emp |
| exam |
| for_delete |
| score |
| student |
| student1 |
| t_check |
| t_recored |
| t_recored_old |
| t_truncate |
| users |
| v_student_score |
| v_student_score_v1|
| v_student_total_points |
+-------------------+
17 rows in set (0.00 sec)查询数据
mysql> select * from student;
+----+-----------+--------+-----+--------+------------+----------+
| id | name | sno | age | gender | enroll_date| class_id |
+----+-----------+--------+-----+--------+------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
| 7 | 李逵 | 200003 | 18 | 1 | 2000-09-01 | 2 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
+----+-----------+--------+-----+--------+------------+----------+
8 rows in set (0.02 sec)写入一条数据时失败,因为没有授权写入权限
mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
ERROR 1142 (42000): INSERT command denied to user 'bit'@'localhost' for table 'student' -
查看
bit@localhost用户权限,USAGE表示在指定的priv_level上没有权限mysql> show grants for 'bit'@'localhost';
+---------------------------------------------+
| Grants for bit@localhost |
+---------------------------------------------+
| GRANT USAGE ON . TO 'bit'@'localhost' |
| GRANT SELECT ONjava01.* TO 'bit'@'localhost' |
+---------------------------------------------+
2 rows in set (0.00 sec) -
为
bit@localhost用户授权于java01数据库的所有权限ALL为所有权限
mysql> grant ALL on java01.* to 'bit'@'localhost';
Query OK, 0 rows affected (0.01 sec)查看用户权限
mysql> show grants for 'bit'@'localhost';
+---------------------------------------------+
| Grants for bit@localhost |
+---------------------------------------------+
| GRANT USAGE ON . TO 'bit'@'localhost' |
| GRANT ALL PRIVILEGES ONjava01.* TO 'bit'@'localhost' |
+---------------------------------------------+
2 rows in set (0.00 sec)插入一条新记录
mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
ERROR 1142 (42000): INSERT command denied to user 'bit'@'localhost' for table 'student'不成功说明权限没有生效,需要刷新权限,如果还不成功可以重新登录
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)重新执行插入操作
mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
Query OK, 1 row affected (0.02 sec)查看记录
mysql> select * from student;
+----+-----------+--------+-----+--------+------------+----------+
| id | name | sno | age | gender | enroll_date| class_id |
+----+-----------+--------+-----+--------+------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
| 7 | 李逵 | 200003 | 18 | 1 | 2000-09-01 | 2 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
| 12 | test | 500001 | 18 | 1 | 2000-06-08 | 1 | # 新记录写入成功
+----+-----------+--------+-----+--------+------------+----------+
9 rows in set (0.00 sec)删除操作
mysql> delete from student where id = 12;
Query OK, 1 row affected (0.01 sec)删除成功
mysql> select * from student;
+----+-----------+--------+-----+--------+------------+----------+
| id | name | sno | age | gender | enroll_date| class_id |
+----+-----------+--------+-----+--------+------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
| 7 | 李逵 | 200003 | 18 | 1 | 2000-09-01 | 2 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
+----+-----------+--------+-----+--------+------------+----------+
8 rows in set (0.00 sec)
1.2 回收权限
1.2.1 语法
REVOKE [权限类型] ON [权限范围] FROM '用户名'@'主机名';
REVOKE [IF EXISTS] priv_type[, priv_type] ... ON priv_level
FROM 'user_name'@'host_name' [, 'user_name'@'host_name'] ...
示例:
-- 回收插入权限
REVOKE INSERT ON java01.* FROM 'bit'@'localhost';
-- 刷新权限使其生效
FLUSH PRIVILEGES;
注意:
- 必须刷新权限 执行
REVOKE后,需要运行FLUSH PRIVILEGES;让权限变更立即生效,否则用户的现有连接可能还能继续使用旧权限。
1.2.2 示例
-
回收
bit@localhost用户对于java01数据库的权限mysql> REVOKE all on *. from 'bit'@'localhost';
Query OK, 0 rows affected (0.01 sec)刷新权限
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)查看权限,没有任何授权
mysql> show grants for 'bit'@'localhost';
+---------------------------------------------+
| Grants for bit@localhost |
+---------------------------------------------+
| GRANT USAGE ON . TObit@localhost|
+---------------------------------------------+
1 row in set (0.00 sec)查看所有数据库,没有可以访问的库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)