角色实在Mysql8.0版本中引入的新功能。角色是权限的集合,可以为角色添加或移除权限。用户可以被赋予角色,同事也被授予角色包含的权限。对角色进行操作需要较高的权限。
引入角色的目的是方便管理拥有相同权限的用户。恰当的权限设定,可以确保数据的安全性,这是至关重要的。
在实际应用中,为了安全性,需要给用户授予权限。当户数量较多时,为了避免单独给每一个用户授予多个权限,可以先将权限集合放入角色中,再赋予用户响应的角色。
创建角色使用CREATE ROLE语句,语法如下:
CREATE ROLE 'role_name'[@'host_name']
角色名称的命名规则和用户名类似。如果host_name省略,默认为%,role_name不能省略。
举例:
# 创建一个经理的角色
CREATE ROLE 'manager'@'localhost';
# 创建一个库管角色
CREATE ROLE 'stocker';
# 同时创建多个角色
CREATE ROLE 'app_developer', 'app_read', 'app_write';
创建角色之后,默认这个角色是没有任何权限的,我们需要给角色授权。给角色授权的语法结构是:
GRANT privileges ON table_name TO 'role_name'[@'host_name'];
举例:
# 给经理角色授予商品信息表的只读权限
GRANT SELECT ON demo.setlement TO 'manager';
# 给库管员角色赋予盘点表的增删改查权限
GRANT SELECT, INSERT, DELETE, UPDATE ON demo.invcount TO 'stocker';
# 给经理角色赋予对员工数据库中所有表进行任何操作的权限
GRANT ALL PRIVILEGES ON employees.* TO 'manager';
赋予角色权限之后,可以通过SHOW GRANTS语句查看权限是否创建成功:
SHOW GRANTS FOR 'manager';
角色授权后,可以对角色的权限进行维护,对权限进行添加或撤销。添加权限使用GRANT语句,与角色授权相同,撤销角色或角色权限使用REVOKE语句。
撤销角色权限的SQL语法如下:
REVOKE privileges ON tablename FROM 'rolename';
举例:
# 撤销库管员角色对盘点表的增加,更新,删除权限
REVOKE INSERT, UPDATE, DELETE ON demo.invcount FROM 'stocker';
删除角色的语法如下:
DROP ROLE role;
举例:
# 删除经理角色
DROP ROLE 'manager';
角色创建并授权后,要赋给用户并处于激活状态才能发挥作用。给用户添加角色可使用GRANT语句,语法形式如下:
GRANT role TO user;
举例:
# 给zhangsan赋予经理角色
GRANT 'manager' TO 'zhangsan'@'localhost';
添加完成后,可以使用SHOW GRANTS FOR 语句查看是否添加成功:
SHOW GRANTS FOR 'zhangsan'@'localhost';
使用zhangsan用户登录,然后查询当前角色,如果角色未激活,结果将显示NONE:
SELECT CURRENT_ROLE();
如果当前用户已经赋予角色了,但是角色显示NONE,是因为mysql默认角色都是没有被激活,也就是无法使用,必须手动激活角色。
方式1:使用SET DEFAULT ROLE命令激活角色
举例:
# 给zhangsan默认激活其已拥有的角色
SET DEFAULT ROLE ALL TO 'zhangsan'@'localhost';
方式2:将activate_all_roles_on_login设置为ON
SET GLOBAL activate_all_roles_on_login=ON;
这条语句是对所有角色进行永久激活。
撤销用户角色的sql语法如下:
REVOKE role FROM user;
举例:
REVOKE 'manager' FROM 'zhangsan'@'localhost';
强制角色是给每个创建账户的默认角色,不需要手动设置。强制角色无法被REVOKE或者DROP。
方式1:服务启动前设置
[mysqld]
mandatory_roles='role1,role2@sqllocalhost,role3@%'
方式2:运行时设置
# 系统重启后仍然有效
SET PERSIST mandatory_roles = 'role1,role2@sqllocalhost,role3@%';
# 系统重启后失效
SET GLOBAL mandatory_roles = 'role1,role2@sqllocalhost,role3@%';
与在命令行中指定启动选型不同的是,配置文件中的启动选项被划分为若干个组,每个组有一个组名,用中括号[]括起来,举例如下:
[server]
(具体的启动选项...)
[mysqld]
(具体的启动选项...)
[mysqld_safe]
(具体的启动选项...)
[client]
(具体的启动选项...)
[mysql]
(具体的启动选项...)
[mysqladmin]
(具体的启动选项...)
配置文件中不同的选项组是给不同的启动命令使用的,不过有两个选项组比较特别:
下面是启动命令能读取的选项组:
启动命令 | 类别 | 能读取的组 |
---|---|---|
mysqld | 启动服务器 | [mysql]、[server] |
mysqld_safe | 启动服务器 | [mysql]、[server]、[mysqld_safe] |
mysql.server | 启动服务器 | [mysql]、[server]、[mysql.server] |
mysql | 启动客户端 | [mysql]、[client] |
mysqladmin | 启动客户端 | [mysqladmin]、[client] |
mysqldump | 启动客户端 | [mysqldump]、[client] |
比如在/etc/mysql/my.cnf这个配置文件中添加一些内容:
[server]
skip-networking
default-storage-engine=MyISAM
然后直接用mysqld启动服务器程序:
mysqld
虽然在命令行没有添加启动选项,但是在程序启动的时候,就会默认地到上边提到的配置文件路径下查找配置文件,其中就包括/etc/mysql/my.cnf。又由于mysqld命令可以读取[server]选项组的内容,所以skip-networking
和default-storage-engin这2个选项是生效的。
可以在选型组的名称后加上特定的Mysql版本号,比如对于[mysqld]选项组来说,我们可以定义一个[mysqld-5.7]的选项组,它的含义和[mysqld]一样,只不过只有版本号为5.7的mysqld程序才能使用这个选项组中的选项。
同一个命令可以访问配置文件中的多个组,比如mysqld可以访问[mysqld]、[server]组,如果在同一个配置文件中出现了同样的配置项,那么将会以最后一个出现的组中的启动项为准。例如下例中,会以[mysqld]组中的配置项为准。
[server]
default-storage-engine=MyISAM
[mysqld]
default-storage-engine=InnoDB
如果同一个启动选项既出现在命令行中,又出现在配置文件中,那么就以命令行中的启动选项为准!比如在配置文件中谢了:
[server]
default-storage-engine=MyISAM
而启动命令是:
mysql.server start --default-storage-engine=InnoDB
那么最后default-storage-engine的值就是:InnoDB。