本篇文章主要介绍MySQL数据库的授权,以下内容是笔者学习《数据库系统概念》总结而来,权当笔记。
我们可能会给一个用户在数据库的某些部分授予几种形式的权限,包括:
每种类型的授权都称为一个权限(privilege)。我们可以在数据库的某些特定部分(如某个关系或视图)上授权给用户所有这些类型的权限,或者完全不授权,或者这些权限的一个组合。
当用户提交查询或更新时,SQL执行先基于该用户曾获得过的权限检查此查询或更新是否是授权过的。如果没有经过授权,那么将被拒绝执行。
除了在数据上的授权之外,用户还可以被授予在数据库模式上的权限,例如,可以允许用户创建、修改或删除关系。拥有某些形式的权限的用户还可以把这样的权限转授给其他用户,或者撤销一种此前授出的权限。最大的授权形式是被授予数据库管理员的。数据库管理员可以授权新用户、重构数据库等等。
权限的授予
SQL标准包括select、insert、update和delete权限。所有权限(all privileges)可以用作所有允许权限的简写形式。一个创建了新关系的用户将自动被授予该关系上的所有权限。
SQL数据定义语言包括授予和收回权限的命令,使用grant语句来授予权限。此语句的基本形式为:
GRANT <权限列表>
ON <关系名或视图名>
TO <用户或角色列表>;
权限列表使得一个命令可以授予多个权限。
在举例说明grant语句之前,我们先来学习查询数据库所有用户以及增加一个新用户。查询数据库所有用户语句如下:
SELECT * FROM mysql.user;
新增一个用户语句形式如下:
CREATE USER 用户名
IDENTIFIEDBY '密码';
例如我们想增加一个名为zhaoyanzu,密码为111111的新用户,SQL语句如下:
CREATE USER zhaoyanzu
IDENTIFIED BY '111111';
然后授予zhaoyanzu关系city的查询和更新权限,SQL语句如下:
GRANT select,update
ON country.city
to zhaoyanzu;
关系上的select权限允许用户读取关系中的元组,update权限允许用户修改关系中的任意元组。update权限既可以在关系的所有属性上授予,又可以只在某些属性上授予。只授予某些属性的update权限时,只需要将要授予权限的属性列表放在update后面。如果胜率属性列表(如前述SQL),则授予的是关系中所有属性上的update权限。例如授予zhaoyanzu关系city的查询和city_id与city_name属性的更新权限,SQL语句如下:
GRANT select,update(city_id,city_name)
ON country.city
to zhaoyanzu;
insert权限允许用户向关系中插入元组。并且insert权限也可以指定属性列表,对关系所做的任何插入必须只针对这些属性,系统将其余属性要么赋默认值要么为null。
SQL授权机制可以对整个关系或者一个关系的指定属性授予权限,但是不允许对一个元组的指定元组授权,这种授权意义也不大。
角色
在设计其他系统时,所有的用户在菜单权限或者操作权限上或相同或不同,如果单独为每个用户授予权限无疑是很麻烦的。一种更好的方式是将所有用户按照权限相同的规则划分为多个角色,再指明每个角色应该被授予的权限,有些用户可能有多个角色。当有新的用户注册时,分配给该用户对应权限的角色即可。
数据库中角色(role)的概念也是如此。在数据库中建立一个角色集,可以给角色授予权限,就和给每个用户授权的方式完全一样。每个数据库用户被授予一组他有权扮演的角色啊(也有可能是空的)。任何可以授予给用户的权限都可以授予给角色。给用户授予角色就跟给用户授权一样。
需要注意的是MySQL8才开始支持角色管理,创建角色SQL语句如下所示:
CREATE ROLE role_name;
然后角色就可以像用户那样被授予权限,如下面的语句形式:
GRANT <权限列表>
ON <关系名或视图名>
TO <角色列表>;
角色可以授予给用户,也可以授予给其他角色,如下面的语句形式:
GRANT role1 TO role2;
权限的转移
获得了某些形式授权的用户可能被允许将此授权传递给其他用户。在默认方式下,被授予权限的用户/角色无权把得到的权限再授予给另外的用户/角色。如果我们在授权是允许接受者把得到的权限再传递给其他用户,我们可以在相应的grant命令后面附加with grant option子句或with admin option子句,这两个子句的区别下面会提到。SQL形式如下:
GRANT <权限列表>
ON <关系名或视图名>
TO <用户或角色列表>
WITH GRANT/ADMIN OPTION;
一个对象(关系/视图/角色)的创建者拥有该对象上的所有权限,包括给其他用户授权的权限。
权限的收回
我们可以用revoke语句来收回权限。此语句的形式与grant语句几乎是一样的。
REVOKE <权限列表>
ON <关系名或视图名>
FROM <用户或角色列表>;
例如,要收回用户zhaoyanzu的select和update权限,SQL语句如下:
REVOKE select,update(city_id,city_name)
ON city
FROM zhaoyanzu;
假如超级管理员U1授权给U2,U2又授权给U3,U3又授权给了U4,当U1要收回U2的授权时,U3和U4的授权也被收回。这种从一个用户/角色收回权限可能导致其他用户/角色也失去该权限,这一行为称作级联收回。
有时候我们需要级联删除,有时候并不需要。上面提到权限转移时需要添加with grant option或with admin option子句,这两个都允许用户将授予他们的权限授予其他用户,但有如下不同点: