-
简介
MySQL 的权限系统在实现上比较简单,相关权限信息主要存储在几个被称为grant tables
的系统表中,即:mysql.User, mysql.db, mysql.Host, mysql.table_priv
和mysql.column_priv
。由于权限信息数据量比较小,而且访问又非常频繁,所以 Mysql 在启动的时候,就会将所有的权限信息都 Load 到内存中保存在几个特定的结构中。所以才有我们每次手工修改了权限相关的表之后,都需要执行“FLUSH PRIVILEGES”
命令重新加载 MySQL的权限信息。当然,如果我们通过GRANT,REVOKE
或者DROP USER
命令来修改相关权限, 则不需要手工执行FLUSH PRIVILEGES
命令,因为通过GRANT,REVOKE
或者DROP USER
命令所做的权限修改在修改系统表的同时也会更新内存结构中的权限信息。在 MySQL5.0.2 或更高版本的时候, MySQL 还增加了CREATE USER
命令,以此创建无任何特别权限(仅拥有初始 USAGE权限)的用户,通过CREATE USER
命令创建新了新用户之后,新用户的信息也会自动更新到内存结构中。所以,建议读者一般情况下尽量使用GRANT,REVOKE,CREATE USER
以及DROP USER
命令来进行用户和权限的变更操作,尽量减少直接修改grant tables
来实现用户和权限变更的操作。 -
权限授予与去除
要为某个用户授权,可以使用GRANT
命令,要去除某个用户已有的权限则使用REVOKE
命令。当然,出了这两者之外还有一种比较暴力的办法,那就是直接更新grant tables
系统表。当给某个用户授权的时候,不仅需要指定用户名,同时还要指定来访主机。如果在授权的时候仅指定用户名,则 MySQL 会自动认为是对'username'@'%'
授权。要去除某个用户的的权限同样也需要指定来访主机。
可能有些时候我们还会需要查看某个用户目前拥有的权限,这可以通过两个方式实现,首先是通过执行“SHOW GRANTS FOR 'username'@'hostname'”
命令来获取之前该用户身上的所有授权。另一种方法是查询grant tables
里面的权限信息。 -
权限级别
MySQL 中的权限分为五个级别,分别如下:
Global Level:
Global Level
的权限控制又称为全局权限控制,所有权限信息都保存在mysql.user
表中。Global Level
的所有权限都是针对整个 mysqld 的,对所有的数据库下的所有表及所有字段都有效。如果一个权限是以Global Level
来授予的,则会覆盖其他所有级别的相同权限设置。比如我们首先给abc
用户授权可以UPDATE
指定数据库如test
的t
表,然后又在全局级别REVOKE
掉了abc
用户对所有数据库的所有表的UPDATE
权限。则这时候的abc
用户将不再拥有用对test.t
表的更新权限。
要授予Global Level
的权限,则只需要在执行GRANT
命令的时候,用*.*
来指定适用范围是Global
的即可,当有多个权限需要授予的时候,也并不需要多次重复执行GRANT
命令,只需要一次将所有需要的权限名称通过逗号,
分隔开即可,如下:
root@localhost : mysql 05:14:35> GRANT SELECT,UPDATE,DELETE,INSERT ON *.*TO 'def'@'localhost'; Query OK, 0 rows affected (0.00 sec)
Database Level:
Database Level
是在Global Level
之下,其他三个Level
之上的权限级别,其作用域即为所指定整个数据库中的所有对象。与Global Level
的权限相比,Database Level
主要少了以下几个权限:CREATE USER,FILE,PROCESS,RELOAD,REPLICATION CLIENT,REPLICATION SLAVE,SHOW DATABASES,SHUTDOWN,SUPER
和USAGE
这几个权限,没有增加任何权限。之前我们说过 Global Level 的权限会覆盖底下其他四层的相同权限,Database Level
也一样虽然他自己可能会被Global Level
的权限设置所覆盖,但同时他也能覆盖比他更下层的Table,Column
和Routine
这三层的权限。
如果要授予 Database Level 的权限,则可以有两种实现方式:
- 在执行 GRANT 命令的时候,通过
database.*
来限定权限作用域为database
整个数据库,如下:
root@localhost : mysql 06:06:26> GRANT ALTER ON test.* TO 'def'@'localhost' ; Query OK, 0 rows affected (0.00 sec)
网友评论