《数据库系统概论》课程之实验三:数据控制(安全性部分)
《数据库系统概论》课程之实验三:数据控制(安全性部分)
实验目的
(1)熟悉通过SQL对数据进行安全性控制。
(2)完成书本上习题的上机练习。
实验平台MySQL
MySQL8.0及其图形化工具Navicat Premium。
实验内容和要求
使用SQL对数据进行安全性控制,包括:授权和权利回收。操作完成后查看已授权的用户是否真正具有授予的数据操作的权利;权利收回操作之后的用户是否确实丧失了收回的数据操作的权利)。根据以下要求认真填写实验报告,记录所有的实验用例。
教材:《数据库系统概论》第5版——第四章习题P153
第6题
对下列两个关系模式:
学生(学号,姓名,年龄,性别,家庭住址,班级号)
班级(班级号,班级名,班主任,班长)
使用GRANT语句完成下列授权功能:
(1)授予用户U1对两个表的所有权限,并可给其他用户授权。
(2)授予用户U2对学生表具有查看权限,对家庭住址具有更新权限。
(3)将对班级表查看权限授予所有用户。
(4)将对学生表的查询、更新权限授予角色R1.
(5)将角色R1授予用户U1,并且U1可继续授权给其他角色。
建表
1 |
|
- 注意:先建”班级”表,因为”班级”表的主键”班级号”是”学生”表的字段”班级号”的外键(或者先建”职工“表,后建”部门“表,再使用
ALTER TABLE 学生 ADD FOREIGN KEY (班级号) REFERENCES 班级(班级号);
添加外键)
1
授予用户U1对两个表的所有权限,并可给其他用户授权。
先创建用户U1
1
CREATE USER 'U1'IDENTIFIED BY '123456';
再授予权限
1
2GRANT ALL PRIVILEGES ON `db4.6`.`学生` TO `U1` WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON `db4.6`.`班级` TO `U1` WITH GRANT OPTION;注意,对于MySQL,授予权限时只能使用
WITH GRANT OPTION
使权限可传递。
2
授予用户U2对学生表具有查看权限,对家庭住址具有更新权限。
先创建用户U2
1
CREATE USER 'U2'IDENTIFIED BY '123456';
再授予权限
1
GRANT SELECT,UPDATE(`家庭住址`) ON `学生` TO `U2`;
3
将对班级表查看权限授予所有用户。
由于MySQL没有PUBLIC关键字。故这里创建一个存储过程:把所有用户及其地址读至游标,遍历所有用户及其地址,并用grant语句分别授权,并查看权限进行验证。
1 |
|
结果如下:对所有用户授权成功
4
将对学生表的查询、更新权限授予角色R1
先创建角色R1
1
CREATE ROLE R1
再授予权限
1
2
3GRANT SELECT,UPDATE
ON `学生`
TO R1;
5
将角色R1授予用户U1,并且U1可继续授权给其他角色。
1 |
|
- 在MySQL中,将角色授予用户,,则需要使用
WITH ADMIN OPTION
,而无法使用WITH GRANT OPTION
。 - 只有通过
SET DEFAULT ROLE R1 TO 'U1'
激活,U1才会拥有角色R1的权限。
查看授权结果
1 |
|
U1
U2
R1
第7题
今有以下两个关系模式:
职工(职工号,姓名,年龄,职务,工资,部门号)
部门(部门号,名称,经理名,地址,电话号)
请用SQL语句的GRANT和REVOKE语句(加上视图机制)完成以下授权定义或存取控制功能:
(1)用户王明对两个表有SELECT权限。
(2)用户李勇对两个表有INSERT和DELETE权限。
(3)每个职工只对自己的记录有SELECT权限。
(4)用户刘星对职工表有SELECT权限,对工资字段具有更新权限。
(5)用户张新具有修改这两个表的结构的权限。
(6)用户周平具有对两个表的所有权限(读、插、改、删数据),并具有给其他用户授权的权限。
(7)用户杨兰具有从每个部门职工中SELECT最高工资、最低工资、平均工资的权限,他不能查看每个人的工资。
建表
1 |
|
- 注意:先建”部门”表,因为”部门”表的主键”部门号”是”职工”表的字段”部门号”的外键。(或者先建”职工“表,后建”部门“表,再使用
ALTER TABLE 职工 ADD FOREIGN KEY (部门号) REFERENCES 部门(部门号);
添加外键)
1
用户王明对两个表有SELECT权限。
先创建用户
1
CREATE USER 王明;
再授予权限
1
2GRANT SELECT ON TABLE 职工 TO 王明;
GRANT SELECT ON TABLE 部门 TO 王明;
2
用户李勇对两个表有INSERT和DELETE权限。
先创建用户
1
CREATE USER 李勇;
再授予权限
1
2GRANT INSERT,DELETE ON TABLE 职工 TO 李勇;
GRANT INSERT,DELETE ON TABLE 部门 TO 李勇;
3
每个职工只对自己的记录有SELECT权限。
先创建相应的视图。USER()的返回值是用户名和地址,故假定员工的用户名是”职工“表中的姓名,且从localhost登录数据库。
1
create view 职工视图 as select * from 职工 where CONCAT(职工.姓名,'@localhost')=USER();
因为MySQL没有PUBLIC关键字,故再如6.3一般调用一个存储过程把视图的select权限授予每个用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27delimiter $$
CREATE PROCEDURE grant_select_职工视图_to_pubic ()
BEGIN
DECLARE v_user CHAR ( 32 ); -- 定义变量,用于储存用户名:
DECLARE v_host CHAR ( 32 ); -- 定义变量,用于储存地址:
DECLARE done INT DEFAULT FALSE; -- 定义结束标志
DECLARE cur CURSOR FOR SELECT user,host FROM mysql.USER; -- 定义游标(用户名及其地址)
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- 定义 NOT FOUND类异常的HANDLER:
OPEN cur; -- 打开游标
FETCH cur INTO v_user,v_host; -- 取游标的一行数据到变量,并推进游标
-- 每取一个user,构造一条授权语句,然后执行这条语句
-- 因为grant语句不接受变量,所以只能构造整条语句
WHILE NOT done DO
SET @QUERY = CONCAT( GRANT SELECT ON 职工视图 to \'', v_user,'\'@\'',v_host,'\''); -- 授权语句
PREPARE statement FROM @QUERY;
EXECUTE statement;
DEALLOCATE PREPARE statement;
FETCH cur INTO v_user,v_host; -- 取下一个用户
END WHILE;
CLOSE cur;
END $$
CALL grant_select_职工视图_to_pubic (); -- 调用过程,授权给所有用户:在创建存储过程后,还可以创建一个触发器,使在”职工”表中有新职工的记录时,再使用
GRANT
进行授权(默认该职工的地址为’%’)。(注意,触发器无法定义于对系统表的操作)1
2
3
4
5
6DELIMITER $$
CREATE TRIGGER grant_select_职工视图 AFTER INSERT ON 职工
BEGIN
GRANT SELECT ON `职工视图` TO CONCAT(NEW.姓名,'@%')
END
DELIMITER ; -- 把定界符改回‘;’听说这个地方易出问题,故做个测试:
“职工”表如下:
在”李勇”表查看视图”职工视图”:
可以得到,李勇只能查看自己的记录:
4
用户刘星对职工表有SELECT权限,对工资字段具有更新权限。
先创建用户
1
CREATE USER 刘星;
再授予权限
1
GRANT SELECT,UPDATE(工资) ON TABLE 职工 TO 刘星;
5
用户张新具有修改这两个表的结构的权限。
先创建用户
1
CREATE USER 张新;
再授予权限
1
2GRANT ALTER ON TABLE 职工 TO 张新;
GRANT ALTER ON TABLE 部门 TO 张新;
6
用户周平具有对两个表的所有权限(读、插、改、删数据),并具有给其他用户授权的权限。
先创建用户
1
CREATE USER 周平;
再授予权限
1
2GRANT ALL PRIVILEGES ON TABLE 职工 TO 周平 WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON TABLE 部门 TO 周平 WITH GRANT OPTION;
7
用户杨兰具有从每个部门职工中SELECT最高工资、最低工资、平均工资的权限,他不能查看每个人的工资。
创建用户
1
CREATE USER 杨兰;
创建含每个部门职工最高工资、最低工资、平均工资的视图
1
2
3
4
5CREATE VIEW 部门工资 AS
SELECT 部门.名称,MAX(工资),MIN(工资),AVG(工资)
FROM 部门,职工
WHERE 部门.部门号=职工.部门号
GROUP BY 职工.部门号;给杨兰授予SELECT该视图的权限
1
GRANT SELECT ON 部门工资 TO 杨兰;
第8题
针对习题7中(1)~(7)的每一种情况,撤销个用户所授予的权限。
1
撤销用户王明对两个表的SELECT权限。
1 |
|
2
撤销用户李勇对两个表的INSERT和DELETE权限。
1 |
|
3
撤销每个职工对自己的记录的SELECT权限。
同样使用存储过程:
1 |
|
4
撤销用户刘星对职工表的SELECT权限,对工资字段的更新权限。
1 |
|
5
撤销用户张新修改这两个表的结构的权限。
1 |
|
6
撤销用户周平对两个表的所有权限(读、插、改、删数据)。
1 |
|
7
撤销用户杨兰具有从每个部门职工中SELECT最高工资、最低工资、平均工资的权限,即撤销用户杨兰查看视图”部门工资“的权限。
1 |
|
实验心得
在这次实验中,我总结了以下注意点,从而对SQL语句和数据库的安全性控制更加熟练:
建表时有个细节:对于有外键的表,可以先建立该外键对应主键的表,然后在建具有外键的表时同时使用
FOREIGN ... REFERENCES ...
语句。或者在建完两张表后再使用ALTER
给表添加外键。MySQL的
Grant
操作不能同时对两张表使用。(6.1、7.1、7.5等)对于MySQL,授予权限时,即
GRANT
后所跟的是某些权限,只能使用WITH GRANT OPTION
使权限可传递。而授予角色时,若要用户可继续授权,需要使用WITH ADMIN OPTION
。在MySQL中,权限授予的传播是关联的。需要再加注意的是,只有通过SET DEFAULT ROLE R1 TO 'U1'
激活,U1才会拥有角色R1的权限。(6.1、6.5)由于MySQL没有PUBLIC关键字。故对所有用户进行相同的操作时,可以构建一个存储过程(PROCEDURE),用游标遍历用户名以及地址,达到批量处理的目的,在有许多用户名时能够提升效率。(6.3、7.3)
- 若改变某一个表,或其中的某行后,想要对数据库做固定的操作,可以使用触发器来实现。需要注意的是,MySQL的触发器不支持动态SQL语句。(7.3)
- 视图可以提供一个统一访问数据的接口,即可以允许用户通过视图访问数据的安全机制,而不授予用户直接访问底层表的权限。当用户关心一部分数据时,可以考虑创建一个视图进行查看数据。(7.3、7.7)
Group by
根据一个或多个列对结果集进行分组,从而能使用MAX、MIN、AVG等函数对该组数据进行处理。(7.7)REVOKE
只能撤销已存在的权限。
部分参考链接
本博客所有文章除特别声明外,均为博客作者本人编写整理,转载请联系作者!