MySQL 是一个多用户数据库,具有功能强大的访问控制系统,可以为不同用户指定允许的权限。MySQL的用户分为普通用户和 root 用户两种。root 用户是超级管理员,拥有所有权限,包括创建用户、删除用户和修改用户的密码等管理权限;普通用户只拥有被授予的各种权限。用户管理包括管理用户账户、权限等。
1. user 表
【注】MySQL 5.7.21 版本已 password 字段已从 mysql.user 表中删除,新的字段名是“authentication_string”.
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
权限列:
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
安全列:
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | NULL | |
| x509_issuer | blob | NO | | NULL | |
| x509_subject | blob | NO | | NULL | |
| plugin | char(64) | NO | | mysql_native_password | |
| authentication_string | text | YES | | NULL | |
资源控制列:
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
(1). 用户列
用户列包括 Host(主机名)、User(用户名)、Password(密码)。User和Host为user表的联合主键。当用户与服务器之间建立连接时,输入的用户名称、主机名和密码必须匹配 User 表中对应的字段,只有 3 个值都匹配时,才允许建立连接。修改用户密码时,实际就是修改 user 表的 password 字段的值。
(2). 权限列
权限列的字段决定了用户的权限,描述了在全局范围内允许对数据和数据库进行的操作,包括查询权限、修改权限等普通权限,还包括关闭服务器、超级权限和加载用户等高级权限,普通权限用于操作数据库,高级权限用于数据库管理。user 表中对应的权限是针对所有用户数据库的。这些字段值的类型为 ENUM,可以取的值只能为 Y 和 N, Y 表示该用户有对应的权限,N 表示用户没有对应的权限。查看 use 表的结构可以看到,这些字段的值默认都是 N。如果要修改权限,可以使用GRANT 语句或 UPDATE 语句更改 user 表中的这些字段来实现。
(3). 安全列
安全列只有 6 个字段,其中两个是 ssl 相关的,2个是 x509 相关的,另外 2 个是授权插件相关的 。ssl 用于加密; X509 标准可用于标识用户; Plugin 字段标识可以用于验证用户身份的插件,如果该字段为空,服务器使用内建授权验证机制验证用户身份。读者可以通过 SHOW VARIABLES LIKE 'have_openssl' 语句来查询服务器是否支持ssl功能。
(4). 资源控制列
资源控制列的字段用来限制用户使用的资源,包含 4 个字段。- max_questions: 用户每小时允许执行的查询操作次数。
- max_updates: 用户每小时允许执行的更新操作次数。
- max_connections: 用户每小时允许执行的连接操作次数。
- max_user_connections: 用户允许同时建立的连接次数。
2. db 表和 host 表
db 表和 hos t表是 MySQL 数据中非常重要的权限表。db 表中存储了用户对某个数据库的操作权限,决定了用户能从哪个主机存取哪个数据库。host 表中存储了某个主机对数据库的操作权限,配合 db 权限表对给定主机上的数据库级操作权限做更细致的控制,不受 GRANT 和 REVOKE 语句的影响。db 表比较常用,host 表一般很少使用。db 表和 host 表结构相似,字段大致可以分为两类:用户列和权限列。
db 表的结构
mysql> DESC db;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
+-----------------------+---------------+------+-----+---------+-------+
(1). 用户列
db 表的用户列有三个字段,分别是 Host、User、Db, 标识从某个主机连接某个用户对某个数据库的操作权限,这三个字段的组合构成了 db 表的主键。host 表不存储用户名称,用户列只有两个字段,分别是 Host 和 Db,表示从某个主机连接的用户对某个数据库的操作权限,这两个字段构成了 Host 表的主键。host 很少用到,一般情况下 db 表就可以满足权限控制需求了。(2). 权限列
db 表和 host 表的权限列大致相同,表中 Create_routine_priv 和 Alter_routine_priv 这两个字段表明用户是否有创建和修改存储过程的权限。user表中的权限是针对所有数据库的,如果希望用户只对某个数据库有操作权限,那么需要将 user 表中对应的权限设置为N,然后在 db 表中设置对应数据库的操作权限。
【例】有一个名为 Zhangting 的用户分别从名为 large.domain.com 和 smalldomain.com 的两个主机连接到数据库,并需要操作 books 数据库,这时,可以将用户名称 Zhangting 添加到 db 表中,然后将两个主机地址分别作为两条记录的 host字段值添加到 host 表中,并将两个表的数据库字段设置为相同的值 books. 当有用户连接到 MySQL 服务器时,db 表中没有用户登录的主机名称,则 MySQL 会从 host 表中查找相匹配的值,并根据查询的结果决定用户的操作是否被允许。
3. tables_priv 表和 columns_priv 表
tables_priv 表用来对表设置操作权限,columns_priv 表用来对表的某一列设置权限。
tables_priv 表的结构
mysql> DESC tables_priv;
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Grantor | char(93) | NO | MUL | | |
| Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| Table_priv | set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') | NO | | | |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------+
columns_priv 表的结构
mysql> DESC columns_priv;
+-------------+----------------------------------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------------------------------+------+-----+-------------------+-----------------------------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Column_name | char(64) | NO | PRI | | |
| Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+----------------------------------------------+------+-----+-------------------+-----------------------------+
table_priv 表有 8 个字段,各字段说明如下:
- Host、 Db、User和Table_name 4个字段分别表示主机名、数据库名、用户名和表名。
- Grantor 字段表示修改该记录的用户。
- Timestamp 字段表示修改该记录的时间。
- Table_priv 表示对表的操作权限包括 Select、 Insert、Update、 Delete、 Create、Drop、Grant 、References、Index 和 Alter。
- Column_priv 字段表示对表中的列的操作权限,包括 Select、 Insert、 Update 和 References。
4. procs_priv 表
procs_priv 表可以对存储过程和存储函数设置操作权限。procs_priv 表的结构如下所示:mysql> DESC procs_priv ;
+--------------+----------------------------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------------------------------------+------+-----+-------------------+-----------------------------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Routine_name | char(64) | NO | PRI | | |
| Routine_type | enum('FUNCTION','PROCEDURE') | NO | PRI | NULL | |
| Grantor | char(93) | NO | MUL | | |
| Proc_priv | set('Execute','Alter Routine','Grant') | NO | | | |
| Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+--------------+----------------------------------------+------+-----+-------------------+-----------------------------+
- Host、Db 和 User 字段分别表示主机名、数据库名和用户名。
- Routine_name 字段表示存储过程或函数的名称。
- Routine_type 字段表示存储过程或函数的类型。
- Routine_type 字段有两个值,分别是 FUNCTION 和 PROCEDURE。 FUNCTION 表示这是一个函数; PROCEDURE表示这是一个存储过程。
- Grantor 字段是插入或修改该记录的用户。
- Proc_priv 字段表示拥有的权限,包括 Execute、Alter Routine 和 Grant 三种。
- Timestamp 字段表示记录更新的时间。
【注】参考于清华大学出版社《MySQL数据库应用案例课堂》2016年1月第1版