课程 › 第 8 章 › 实验三
第 8 章 · 实验三 · 在第四节之后

角色管理

创建角色并给角色授权,把角色分配给用户,激活后检验权限,最后撤销和删除角色。

环 境

MySQL 8.0 和 MySQL Workbench,机房电脑已装好。所有语句在 Workbench 的 SQL 编辑区中执行。

执 行

Ctrl+Enter 执行光标所在的一句,Ctrl+Shift+Enter 执行全部。Mac 上把 Ctrl 换成 ⌘。

注 意

输入法切到英文。表名、字段名不加引号,字符串值才用单引号。

本次实验的顺序 后一个实验用到前一个的结果

  1. 实验 3-1创建角色
  2. 实验 3-2给角色授权
  3. 实验 3-3把角色分配给用户
  4. 实验 3-4激活角色
  5. 实验 3-5撤销和删除角色
第一步

数据准备(必做)

与实验一相同的脚本。执行后本章的用户和角色都被删除,teaching 库恢复教材数据。

整段复制,全部执行下载 .sql
-- 第 8 章实验数据:删除本章用到的用户和角色,并重建教材 teaching 库的五张表
-- 用 root 连接整段执行。三次实验共用,想从头再做时重新执行即可。
DROP USER IF EXISTS 'student'@'localhost', 'teacher1'@'%', 'teacher2'@'localhost',
  'teacher3'@'localhost', 'teacher4'@'localhost', 'teacher10'@'localhost';
DROP ROLE IF EXISTS 'teacher', 'administrator', 'developer'@'localhost';

CREATE DATABASE IF NOT EXISTS teaching DEFAULT CHARACTER SET utf8mb4;
USE teaching;

-- 删除第 7 章实验建的视图
DROP VIEW IF EXISTS s_view, s_sc_c_view, s_maj_view, s_update_view, c_count_view, maj_view, s_sc_view, s_lxy_view;

-- 删除旧的表。先暂时关闭外键检查,库里有别的表引用它们时也能删除
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS sc, tc, avgsal, classroom, s, c, t;
SET FOREIGN_KEY_CHECKS = 1;

-- 课程表
CREATE TABLE c (
  cno CHAR(4) NOT NULL,
  cn VARCHAR(30) NOT NULL,
  ct INT,
  PRIMARY KEY (cno)
);
-- 学生表
CREATE TABLE s (
  sno CHAR(4) NOT NULL,
  sn VARCHAR(20) NOT NULL,
  sex CHAR(2),
  age INT,
  maj VARCHAR(30),
  dept VARCHAR(30),
  PRIMARY KEY (sno)
);
-- 教师表
CREATE TABLE t (
  tno CHAR(4) NOT NULL,
  tn VARCHAR(20) NOT NULL,
  sex CHAR(2),
  age INT,
  prof VARCHAR(20),
  maj VARCHAR(30),
  dept VARCHAR(30),
  sal DECIMAL(8,2),
  PRIMARY KEY (tno)
);
-- 选课表
CREATE TABLE sc (
  sno CHAR(4) NOT NULL,
  cno CHAR(4) NOT NULL,
  score DECIMAL(5,2),
  PRIMARY KEY (sno, cno),
  FOREIGN KEY (sno) REFERENCES s (sno),
  FOREIGN KEY (cno) REFERENCES c (cno)
);
-- 授课表
CREATE TABLE tc (
  tno CHAR(4) NOT NULL,
  cno CHAR(4) NOT NULL,
  tcdate DATE,
  PRIMARY KEY (tno, cno),
  FOREIGN KEY (tno) REFERENCES t (tno),
  FOREIGN KEY (cno) REFERENCES c (cno)
);

INSERT INTO c VALUES
('c1','Java程序设计',40), ('c2','程序设计基础',48), ('c3','线性代数',48),
('c4','数据结构',64), ('c5','数据库系统',56), ('c6','数据挖掘',32),
('c7','高等数学',60), ('c8','控制理论',32);

INSERT INTO s VALUES
('s1','王彤','女',18,'计算机','信息学院'),
('s2','苏乐','男',20,'信息','信息学院'),
('s3','林欣怡','女',19,'信息','信息学院'),
('s4','陶然','男',19,'自动化','工学院'),
('s5','魏立','男',17,'数学','理学院'),
('s6','何欣荣','女',21,'计算机','信息学院'),
('s7','赵琳琳','女',19,'数学','理学院'),
('s8','李轩','男',18,'自动化','工学院');

INSERT INTO t VALUES
('t1','刘杨','男',38,'教授','计算机','信息学院',3800.00),
('t2','石丽','女',28,'讲师','计算机','信息学院',2800.00),
('t3','顾伟','男',35,'副教授','计算机','信息学院',3200.00),
('t4','赵礼','男',45,'教授','自动化','工学院',4267.90),
('t5','赵希希','女',33,'副教授','数学','理学院',3332.67),
('t6','张刚','男',30,'讲师','计算机','工学院',2600.00);

INSERT INTO sc VALUES
('s1','c1',90.50), ('s1','c2',88.00),
('s2','c4',70.00), ('s2','c5',57.00), ('s2','c6',81.50), ('s2','c7',NULL),
('s3','c1',75.00), ('s3','c2',76.50), ('s3','c4',85.00),
('s4','c1',93.00), ('s4','c2',82.00), ('s4','c6',NULL), ('s4','c7',68.00),
('s5','c2',79.00), ('s5','c7',84.00),
('s7','c3',77.00), ('s7','c5',62.00), ('s7','c7',100.00),
('s8','c2',66.00), ('s8','c3',96.00);

INSERT INTO tc VALUES
('t1','c1','2021-09-03'), ('t1','c2','2021-09-04'),
('t2','c5','2021-03-06'), ('t2','c6','2021-09-06'),
('t3','c2','2021-03-08'), ('t3','c4','2021-09-08'),
('t4','c3','2021-03-10'),
('t5','c7','2021-09-12'), ('t5','c8','2021-03-15');
3-1

创建角色

讲义 · 创建角色
目的
用 CREATE ROLE 创建角色,在 mysql.user 中查看角色。
前提
已用 root 连接执行数据准备。
  1. 创建教师角色 teacher 和管理员角色 administrator,可在任何主机上使用
  2. 创建只能在本机使用的开发者角色 developer
  3. 在 mysql.user 中查看这三个角色

参考答案

可以直接复制到 Workbench 执行
CREATE ROLE 'teacher', 'administrator';
CREATE ROLE 'developer'@'localhost';
SELECT User, Host, account_locked FROM mysql.user
WHERE User IN ('teacher', 'administrator', 'developer');

语句解释

CREATE ROLE 'teacher'省略 @主机 时主机为 %,全名是 teacher@%
account_lockedY 表示账户被锁定。角色不能用来登录
执行后看:三个角色都在 mysql.user 中,account_locked 都是 Y。
3-2

给角色授权

讲义 · 给角色授权
目的
把权限授予角色,写法和给用户授权相同。
前提
已完成实验 3-1。
  1. 给 administrator 授予服务器上的全部权限
  2. 给 teacher 授予 teaching 库 sc 表的 SELECT、INSERT、UPDATE、DELETE 权限
  3. 查看 teacher 的权限

参考答案

可以直接复制到 Workbench 执行
GRANT ALL PRIVILEGES ON *.* TO 'administrator';
GRANT SELECT, INSERT, UPDATE, DELETE ON teaching.sc TO 'teacher';
SHOW GRANTS FOR 'teacher';

语句解释

GRANT ALL PRIVILEGES ON *.*全局的全部权限
ON teaching.sc TO 'teacher'表级权限授予角色 teacher
执行后看:teacher 的权限有两行:USAGE 和 sc 表上的四项权限。
3-3

把角色分配给用户

讲义 · 分配与激活
目的
创建用户 teacher2,把 teacher 角色分配给它,检验分配后能否直接使用。
前提
已完成实验 3-2。

执行完 root 的语句后,按实验 1-3 的方法,用 teacher2(口令 t2123)新建一个连接并打开。

  1. 创建只能从本机登录的用户 teacher2,口令为 t2123
  2. 把 teacher 角色分配给 teacher2,查看 teacher2 的权限
  3. 用 teacher2 登录,查看当前角色,再查询选课表

参考答案

在 root 的连接中执行
CREATE USER 'teacher2'@'localhost' IDENTIFIED BY 't2123';
GRANT 'teacher' TO 'teacher2'@'localhost';
SHOW GRANTS FOR 'teacher2'@'localhost';
在 teacher2 的连接中执行
SELECT CURRENT_ROLE();
-- 角色还没有激活,这一句会报错 1142
SELECT COUNT(*) FROM teaching.sc;

语句解释

GRANT 'teacher' TO 'teacher2'@'localhost'把角色分配给用户,GRANT 后面写角色名
CURRENT_ROLE()返回当前连接中已激活的角色,NONE 表示没有
报错 1142角色分配了但没有激活,teacher2 还没有 sc 表的权限
执行后看:SHOW GRANTS 中多了 GRANT `teacher`@`%` TO `teacher2`@`localhost`。teacher2 的 CURRENT_ROLE() 是 NONE,查询 sc 报错 1142。
3-4

激活角色

讲义 · 分配与激活
目的
用 SET ROLE 在当前连接中激活角色,用 SET DEFAULT ROLE 设置登录时自动激活。
前提
已完成实验 3-3,teacher2 的连接还开着。

最后一段要先关掉 teacher2 的连接,再重新打开。

  1. 在 teacher2 的连接中激活 teacher 角色,再查询选课表
  2. 在 root 的连接中,把 teacher 设为 teacher2 的默认角色
  3. 重新连接 teacher2,查看当前角色并查询选课表

参考答案

在 teacher2 的连接中执行
SET ROLE 'teacher';
SELECT CURRENT_ROLE();
SELECT COUNT(*) FROM teaching.sc;
在 root 的连接中执行
SET DEFAULT ROLE 'teacher' TO 'teacher2'@'localhost';
在 teacher2 的连接中执行(重新连接后)
SELECT CURRENT_ROLE();
SELECT COUNT(*) FROM teaching.sc;

语句解释

SET ROLE 'teacher'在当前连接中激活角色,断开连接后失效
SET DEFAULT ROLE … TO …设置默认角色,用户以后每次登录都自动激活
SELECT COUNT(*) FROM teaching.sc角色激活后,teacher2 能查询选课表
执行后看:SET ROLE 后 CURRENT_ROLE() 是 `teacher`@`%`,能查到 20 行。重新连接后不用 SET ROLE,角色已经自动激活。
3-5

撤销和删除角色

讲义 · 查看与撤销角色
目的
用 REVOKE 撤销用户的角色,用 DROP ROLE 删除角色。
前提
已完成实验 3-4。

执行完 root 的语句后,关掉 teacher2 的连接再重新打开。

  1. 查看 teacher2 通过 teacher 角色得到的权限
  2. 撤销 teacher2 的 teacher 角色
  3. 删除三个角色
  4. 重新连接 teacher2,再查询选课表

参考答案

在 root 的连接中执行
SHOW GRANTS FOR 'teacher2'@'localhost' USING 'teacher';
-- 先写角色,FROM 后面写用户
REVOKE 'teacher' FROM 'teacher2'@'localhost';
SHOW GRANTS FOR 'teacher2'@'localhost';
DROP ROLE 'teacher', 'administrator', 'developer'@'localhost';
在 teacher2 的连接中执行(重新连接后)
SELECT CURRENT_ROLE();
-- 角色已撤销,这一句会报错 1142
SELECT COUNT(*) FROM teaching.sc;

语句解释

USING 'teacher'把角色中的权限也展开显示
REVOKE 'teacher' FROM 'teacher2'@'localhost'撤销角色,FROM 前面是角色,后面是用户
DROP ROLE删除角色,一次可以删除多个
执行后看:第一句显示 teacher2 通过角色得到了 sc 表的四项权限。撤销后只剩 USAGE。重新连接的 teacher2 查询 sc 报错 1142。
保山学院·人工智能教研室·曹鼎鼎