准备数据
root 在 Workbench 首页双击 root 的连接,打开 SQL 编辑区。这个标签页整节课都开着。
root 复制下面整段脚本,粘贴进编辑区,按 Ctrl+Shift+Enter 全部执行。
root 中整段执行下载 .sql-- 第 8 章上机练习:准备数据(用 root 整段执行,可以反复执行) -- 1. 删除本练习会创建的账号和角色 DROP USER IF EXISTS 'jiaowu'@'localhost', 'fudao'@'localhost', 'zhuli'@'localhost', 't_liu'@'localhost'; DROP ROLE IF EXISTS 'r_teacher'; -- 2. 重建 teaching 库 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. 检查数据 SELECT COUNT(*) AS 学生数 FROM s; SELECT COUNT(*) AS 教师数 FROM t; SELECT COUNT(*) AS 选课数 FROM sc;应看到最后三个结果依次是 8、6、20。
创建用户
root 用一条语句创建三个用户,都只能从本机登录:jiaowu 口令 jw123,fudao 口令 fd123,zhuli 口令 zl123。
格式
CREATE USER '用户名'@'localhost' IDENTIFIED BY '口令', '用户名'@'localhost' IDENTIFIED BY '口令', …;看答案
root 中执行CREATE USER 'jiaowu'@'localhost' IDENTIFIED BY 'jw123', 'fudao'@'localhost' IDENTIFIED BY 'fd123', 'zhuli'@'localhost' IDENTIFIED BY 'zl123';应看到执行成功,没有报错。
root 查看这三个用户在不在。
格式
SELECT User, Host FROM mysql.user WHERE User IN (…);看答案
root 中执行SELECT User, Host FROM mysql.user WHERE User IN ('jiaowu', 'fudao', 'zhuli');应看到查到 3 行,Host 都是 localhost。
root 学生助理觉得口令太简单,把 zhuli 的口令改成 zl456。
格式
ALTER USER '用户名'@'主机' IDENTIFIED BY '新口令';看答案
root 中执行ALTER USER 'zhuli'@'localhost' IDENTIFIED BY 'zl456';
应看到执行成功。以后 zhuli 要用 zl456 登录。
新用户能做什么
zhuli 用 zhuli(口令 zl456)新建一个连接,并打开它。
做法首页 MySQL Connections 右边点 ⊕ → Connection Name、Username 都填 zhuli → Test Connection,输入 zl456 → OK → 双击打开。
应看到多了一个标签页,标题是 zhuli。
zhuli 看看 zhuli 能看到哪些数据库。
zhuli 中执行SHOW DATABASES;
应看到只有 information_schema 和 performance_schema,看不到 teaching。
zhuli 试着进入 teaching 库。
zhuli 中执行USE teaching;
应看到报错 1044。新用户只能登录,还没有任何权限——这正是下一项要解决的。
授权
root 教务员 jiaowu 管整个 teaching 库:能查询、插入、修改、删除。
格式
GRANT 权限1, 权限2, … ON 库名.* TO '用户名'@'主机';看答案
root 中执行GRANT SELECT, INSERT, UPDATE, DELETE ON teaching.* TO 'jiaowu'@'localhost';
应看到执行成功。
root 辅导员 fudao 只能查询学生表 s。
格式
GRANT 权限 ON 库名.表名 TO '用户名'@'主机';看答案
root 中执行GRANT SELECT ON teaching.s TO 'fudao'@'localhost';
应看到执行成功。
root 学生助理 zhuli 只能看教师表 t 的 tno、tn 两列。
格式
GRANT SELECT(字段1, 字段2) ON 库名.表名 TO '用户名'@'主机';看答案
root 中执行GRANT SELECT(tno, tn) ON teaching.t TO 'zhuli'@'localhost';
应看到执行成功。
root 查看三个人的权限。
格式
SHOW GRANTS FOR '用户名'@'主机';看答案
root 中执行SHOW GRANTS FOR 'jiaowu'@'localhost'; SHOW GRANTS FOR 'fudao'@'localhost'; SHOW GRANTS FOR 'zhuli'@'localhost';
应看到每人两行:第一行是 GRANT USAGE …,第二行是刚才授的权限。
检验权限
把 zhuli 的标签页关掉,再双击重新打开(权限改了要重新连接);再给 fudao(fd123)和 jiaowu(jw123)各建一个连接。
应看到现在开着 root、zhuli、fudao、jiaowu 四个标签页。
zhuli 查教师的工号和姓名。
zhuli 中执行SELECT tno, tn FROM teaching.t;
应看到查到 6 行。
zhuli 再试着查工资。
zhuli 中执行SELECT tn, sal FROM teaching.t;
应看到报错 1143:sal 这一列没有授权,整句都不执行。
fudao 查学生表。
fudao 中执行SELECT * FROM teaching.s;
应看到查到 8 行。
fudao 再试着查课程表。
fudao 中执行SELECT * FROM teaching.c;
应看到报错 1142:课程表 c 没有授权给 fudao。
jiaowu 往课程表加一门课。
jiaowu 中执行INSERT INTO teaching.c VALUES ('c9', '数据库原理', 48);应看到插入成功。库级权限对 teaching 中的每张表都有效。
收回权限
root 收回 jiaowu 在 teaching 库上的 DELETE 权限,再查看他的权限。
格式
REVOKE 权限 ON 库名.* FROM '用户名'@'主机';和 GRANT 一样,只是 TO 换成 FROM看答案
root 中执行REVOKE DELETE ON teaching.* FROM 'jiaowu'@'localhost'; SHOW GRANTS FOR 'jiaowu'@'localhost';
应看到teaching.* 那一行只剩 SELECT, INSERT, UPDATE。
jiaowu 关掉 jiaowu 的标签页再重新打开,试着删掉刚加的 c9。
jiaowu 中执行DELETE FROM teaching.c WHERE cno = 'c9';
应看到报错 1142:DELETE command denied。权限已经收回了。
root 由 root 删掉 c9,把数据恢复原样。
看答案
root 中执行DELETE FROM teaching.c WHERE cno = 'c9';
应看到删除 1 行。
角色
root 创建角色 r_teacher,给它选课表 sc 的查询权限。
格式
CREATE ROLE '角色名';GRANT 权限 ON 库名.表名 TO '角色名';看答案
root 中执行CREATE ROLE 'r_teacher'; GRANT SELECT ON teaching.sc TO 'r_teacher';
应看到两句都执行成功。
root 创建刘老师的账号 t_liu(只能本机登录,口令 liu123),把角色分给他。
格式
GRANT '角色名' TO '用户名'@'主机';分角色时没有 ON看答案
root 中执行CREATE USER 't_liu'@'localhost' IDENTIFIED BY 'liu123'; GRANT 'r_teacher' TO 't_liu'@'localhost';
应看到两句都执行成功。
t_liu 给 t_liu 建连接并打开,看看当前角色,再查选课表。
t_liu 中执行SELECT CURRENT_ROLE(); SELECT COUNT(*) FROM teaching.sc;
应看到第一句是 NONE,第二句报错 1142:角色分给他了,但还没激活。
root 激活:把 r_teacher 设为 t_liu 的默认角色。
格式
SET DEFAULT ROLE '角色名' TO '用户名'@'主机';看答案
root 中执行SET DEFAULT ROLE 'r_teacher' TO 't_liu'@'localhost';
应看到执行成功。
t_liu 关掉 t_liu 的标签页再重新打开,把第 3 步的两句再执行一次。
t_liu 中执行SELECT CURRENT_ROLE(); SELECT COUNT(*) FROM teaching.sc;
应看到第一句是 `r_teacher`@`%`,第二句查到 20。激活以后,权限才生效。