文章目录
- 基本概念
- 数据库基本概念
- 关系数据结构
- 完整性约束
- 关系代数
- 关系代数练习
- 课堂练习
- 语法树
基本概念
数据库基本概念
DB 数据库, 为了存用户的各种数据,我们要建很多关系(二维表),所以把相关的关系(二维表)放在一起,形成一个库
DBMS 数据库管理系统 ,数据库要放硬盘,好麻烦,牛的程序员给我们做了一个软件, 让我们可以方便的建库, 建表,做权限控制等,这就是DBMS
DBS 数据库系统
关系数据结构
元组(Tuple)
关系中的每一行叫作一个n元组(n-tuple)或简称元组(Tuple)。
属性(Attribute)
关系中的每一列为一个属性。
分量(Component)
一个元组(d1,d2,…,dn)中的每一个项di叫作一个分量,即属性值。
域(Domain)
一组具有相同数据类型的值的集合。
基数(Cardinal number)
元组个数
关系模式
关系是元组的集合,其具有如下性质
- 列是同质的(Homogeneous)
- 不同的列可出自同一个域
- 列的顺序无所谓,列的次序可以任意交换
- 任意两个元组的key(码)值不能相同
- 行的顺序无所谓,行的次序可以任意交换
- 分量必须取原子值,每一个分量都必须是不可分的数据项
关系是具有相同结构的元组的集合;
关系模式对关系的结构等的抽象描述;
关系数据库是关系的集合;
外码
设F是基本关系R的一个或一组属性,但不是关系R的码。K是基本关系S的主码。如果F的取值源自基本关系S中的主码K对应的域,则称F是基本关系R的外码。
外码的使用
- 目标关系S的主码K 和参照关系R的外码F必须定义在同一个(或一组)域上;
- 外码并不一定要与相应的主码同名;
- 关系R和S可以是同一个关系。
完整性约束
实体完整性规则
参照完整性规则
用户定义的完整性规则
实体完整性规则(Entity Integrity)
若属性A是基本关系R的主属性,则A不能取空值(NULL)
参照完整性规则
若属性(或属性组)F是基本关系R的外码,则F的值:
或者取空值(F的每个属性的取值均为空值);
或者等于S中某个元组的主码值。
关系代数
- 集合操作:并
- 集合操作:差
- 集合操作:交
- 选择
- 投影
- 重命名
命名操作简化
- 链接运算符
- 笛卡尔积
- θ连接( θ Join)
- 内连接
注意:等值连接表示先做笛卡尔积(×)之后,对相应列进行选择或等值关联后的结果(仅筛选行、不筛选列)
注2:自然连接表示两个关系中若有相同名称的属性,则自动作为关联条件,且仅列出一列
- 外连接
例题
- 除运算
例题
- 去重操作符
- 排序操作符
默认是升序,小的在上面
- ASC :升序(默认值)
- DESC:降序
- 分组操作符
L中有属性就分组,如果只有聚合函数,就是简单的聚合函数,不会分组,如题11
- 聚集操作符
关系代数练习
答案
课堂练习
1. select sno from SC where cno = '2';
2. select sno,sname from Student where sdept = 'IS';
3. select sno,sname from Student where ssex = '女';
4. select cname,grade from SC join Course as c on SC.cno = C.cno where SC.sno =
(select sno from Student where sname = '李勇');
5. select s.sno from Student as s where s.sno not in (select SC.sno from SC);
6. select C.cno,C.cname from Course as C where cno not in (select SC.cno from SC);
SELECT C.cno, C.cname
FROM Course AS C
LEFT JOIN SC ON C.cno = SC.cno
WHERE SC.cno IS NULL;
7. select sno,sname from Student where sdept = (select sdept from Student where sname = '张立') and sname <> '张立';
8. select s.sno,s.sname from Student as s where s.sno in
(select SC.sno from SC join Course as c on SC.cno = c.cno where c.canme = '数学课');
9. select s.sno,s.sname from Student as s where s.sno not in
(select SC.sno from SC join Course as c on SC.cno = c.cno where c.canme = '操作系统')
数据库:
CREATE TABLE Student
( Sno CHAR(9) PRIMARY KEY,
Sname CHAR(8) NOT NULL,
Ssex CHAR(2) CHECK ( Ssex IN (‘男’,‘女’) ) ,
Sage SMALLINT CHECK ( sage >0) ,
Sdept CHAR(20),
FOREIGN KEY (Sdept) REFERENCES depart(dptno)
);
CREATE TABLE SC
( Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno, Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno),
FOREIGN KEY (Cno) REFERENCES Course(Cno)
);
例题1某职工社团管理系统有如下3个基本表:
- 职工( 职工号 ,姓名,年龄,性别)
- 社会团体( 编号 ,名称,负责人,活动地点)
- 参与( 职工号,编号 ,参与日期)
其中:
职工表的主码为职工号,职工姓名不能为空。
社会团体表的主码为编号,外码为负责人,被参照表为职工表,参照属性为职工号,社会团体名称不能为空。
参与表的主码为职工号和编号,职工号为外码,被参照表为职工表,参照属性为职工号,编号为外码,被参照表为社会团体表,参照属性为编号。
试用SQL语句实现以下操作。
(1)定义职工表、社会团体表和参与表,并说明其主码和参照关系。
(2)定义两个视图:
社团负责人(编号,名称,负责人职工号,负责人姓名,负责人性别)
参与人情况(职工号,姓名,社团编号,社团名称,参与日期)
(3)查询参与羽毛球队、秧歌队或冬泳队的职工号和姓名。
(4)查询参与冬泳队且年龄大于50岁的职工的职工号和姓名。
(5)查询还没有确定负责人的社会团体编号和名称。
(6)查询没有参与任何社会团体的职工情况。
(7)查询姓“李”且参与至少一个社会团体的男员工的平均年龄。
(8)查询与“肖波”至少参与一个相同社会团体的所有职工信息。
(9)查询年龄在45~55岁之间的女职工或年龄在50~60岁之间的男职工的所有信息。
(10)查询参与了全部社会团体的职工情况。
(11)查询参与了职工号为“0001”的职工所参与的全部社会团体的职工号。
(12)查询与“秧歌队”负责人年龄相同的职工的姓名。
(13)查询比“秧歌队”中所有职工年龄都大的职工的姓名。
(14)查询并统计每个社会团体的名称和参与人数。
(15)查询并统计参与人数最少的社会团体的名称和参与人数。
(16)查询并统计参与人数超过20人的社会团体的名称和负责人。
答案:
(1)
CREATE TABLE 职工(
职工号 CHAR(8) PRIMARY KEY,
姓名 CHAR (8) NOT NULL,
年龄 SMALLINT,
性别 CHAR (2),
CONSTRAINT C1 CHECK (性别 IN ("男","女")))
CREATE TABLE 社会团体 (
编号 CHAR(8) PRIMARY KEY,
名称 CHAR(8) NOT NULL,
负责人 CHAR(8),
活动地点 VARCHAR(50),
CONSTRAINT C2 FOREIGN KEY(负责人) REFERENCES 职工(职工号))
CREATE TABLE 参与 (
职工号 CHAR(8),
编号 CHAR(8),
参与日期 DATETLME,
CONSTRAINT C3 PRIMARY KEY(职工号,编号),
CONSTRAINT C4 FOREIGN KEY (职工号) REFERENCES 职工(职工号))
(2)
CREATE VIEW 社团负责人(编号,名称,负责人职工号,负责人姓名,负责人性别)
AS SELECT 编号,名称,负责人,姓名,性别
FROM 社会团体,职工
WHERE 社会团体.负责人=职工.职工号
CREATE VIEW 参与人情况(职工号,姓名,社团编号,社团名称,参与日期)
AS SELECT 职工.职工号,姓名,社会团体.编号,名称,参与日期
FROM 职工,社会团体,参与
WHERE 职工.职工号=参与.职工号 AND 参与.编号=社会团体.编号
(3)
SELECT DISTINCT 职工.职工号,姓名
FROM 职工,社会团体,参与
WHERE 职工.职工号=参与.职工号 AND 参与.编号=社会团体.编号
AND 社会团体.名称 IN ("羽毛球队","秧歌队","冬泳队")
(4)
SELECT 职工号,姓名
FROM 职工
WHERE 职工号 IN
(SELECT 职工号
FROM 参与
WHERE 编号 IN
(SELECT 编号
FROM 社会团体
WHERE 名称="冬泳队"))
AND 年龄>50
(5)
SELECT 编号,名称
FROM 社会团体
WHERE 负责人 IS NULL
(6)
SELECT *
FROM 职工
WHERE NOT EXISTS (
SELECT *
FROM 参与
WHERE 参与.职工号=职工.职工号)
(7)
SELECT AVG(年龄)
FROM 职工
WHERE 姓名 LIKE "李%" AND性别="男" AND EXISTS (
SELECT *
FROM 参与
WHERE 参与.职工号=职工.职工号)
(8)
SELECT *
FROM 职工 AS E1
WHERE E1.姓名<>"肖波" AND EXISTS
(SELECT J1.编号
FROM 参与 AS J1
WHERE J1.职工号=E1.职工号 AND J1.编号=ANY
(SELECT J2.编号
FROM 职工 AS E2, 参与 AS J2
WHERE E2.职工号=J2. 职工号 AND E2.姓名="肖波"))
(9)
SELECT *
FROM 职工
WHERE ((年龄 BETWEEN 45 AND 55) AND 性别="女") OR
((年龄 BETWEEN 50 AND 60) AND 性别="男")
(10)
SELECT *
FROM 职工
WHERE NOT EXISTS (
SELECT *
FROM 参与
WHERE NOT EXISTS (
SELECT *
FROM 社会团体
WHERE 参与.职工号=职工.职工号 AND 参与.编号=社会团体.编号))
(11)
SELECT 职工号
FROM 职工
WHERE NOT EXISTS (
SELECT *
FROM 参与 AS 参与 1
WHERE 参与 1.职工号="0001" AND NOT EXISTS (
SELECT *
FROM 参与 AS 参与 2
WHERE 参与 2.编号=参与1.编号 AND 参与2.职工号=职工.职工号))
(12)
SELECT 姓名
FROM 职工
WHERE 年龄>(
SELECT 年龄
FROM 职工,社会团体
WHERE 社会团体.负责人=职工.职工号 AND 社会团体.名称="秧歌队")
(13)
SELECT 姓名
FROM 职工
WHERE 年龄>ALL(
SELECT 年龄
FROM 职工,社会团体,参与
WHERE 社会团体.编号=参与.编号 AND 职工.职工号=参与.职工号
AND 社会团体.名称="秧歌队")
(14)
SELECT 社会团体.名称,COUNT(参与.职工号)
FROM 社会团体,参与
WHERE 社会团体.编号=参与.编号
GROUP BY 参与.编号,社会团体.名称
(15)
SELECT 社会团体.名称,COUNT(参与.职工号)
FROM 社会团体,参与
WHERE 社会团体.编号=参与.编号
GROUP BY 参与.编号,社会团体.名称
HAVING COUNT(参与.职工号)<=ALL (
SELECT COUNT(参与.职工号)
FROM 参与
GROUP BY 参与.编号)
(16)
SELECT 社会团体.名称,职工.姓名
FROM 职工,社会团体,参与
WHERE 社会团体.编号=参与.编号
AND 社会团体.负责人=职工.职工号
GROUP BY 参与.编号,社会团体.名称,职工.姓名
HAVING COUNT (参与.编号)>20
例题2某教学管理数据库中有如下3个基本表。
学生:S( S# ,SNAME,AGE,SEX),属性分别表示学号、姓名、年龄和性别。
学习:SC( S#,C# ,GRADE),属性分别表示学号、课程号和成绩。
课程:C( C# ,CNAME,TEACHER),属性分别表示课程号、课程名和教师姓名。
试用SQL语句完成下列操作:
(1)查询年龄大于20岁的男学生的学号和姓名。
(2)查询选修课程名为“操作系统”课程的学生的平均年龄。
(3)查询教师“王明”所授课程的课程号和课程名。
(4)查询选修课程包含教师“王明”所授课程的学生学号。
(5)查询教师“王明”所授课程的每门课程的学生平均成绩。
(6)统计每门课程的学生选修人数(超过10人的课程才统计),要求输出课程号和选修人数,查询结果按选修人数降序排列,若人数相同,则按课程号升序排列。
(7)查询姓张的所有学生的姓名和年龄。
(8)查询成绩为空值的学生学号和课程号。
(9)查询年龄大于女学生平均年龄的男学生姓名和年龄。
(10)查询年龄大于所有女学生年龄的男学生姓名和年龄。
(11)查询选修课程门数超过学号为S0001的学生选修门数的所有学生信息。
(12)查询每个学生的学号、选修课程门数(COUNT_C)和总成绩(TOTAL_G),将查询结果保存在一个名为RESULT的新表中。
(13)将SC中尚无成绩的选课记录删除。
(14)将学生“张三”的学习选课信息全部删去。
(15)将选修“操作系统”课程且不及格的成绩全改为空值。
(16)将低于总平均成绩的女学生成绩提高10%。
(1)
SELECT S#, SNAME
FROM S
WHERE (AGE>20) AND (SEX="男")
(2)
SELECT AVG(AGE)
FROM S
WHERE S# IN
(SELECT S#
FROM SC
WHERE C# IN
(SELECT C#
FROM C
WHERE CNAME="操作系统"
)
)
(3)
SELECT C#, CNAME
FROM C
WHERE TEACHER="王明"
(4)
SELECT DISTINCT S#
FROM SC
WHERE C# IN
(SELECT C#
FROM C
WHERE TEACHER="王明"
)
(5)
SELECT CNAME,AVG(GRADE)
FROM SC JOIN C ON SC. C#=C. C#
WHERE TEACHER="王明"
GROUP BY C#
(6)
SELECT DISTINCT C#, COUNT(S#)
FROM SC
GROUP BY C#
HAVING COUNT(S#)>10
ORDER BY 2 DESC, C# ASC
(7)
SELECT SNAME,AGE
FROM S
WHERE SNAME LIKE "张%"
(8)
SELECT S#, C#
FROM SC
WHERE GRADE IS NULL
(9)
SELECT SNAME, AGE
FROM S AS X
WHERE X.SEX="男" ND X.AGE>
(SELECT AVG(AGE)
FROM S AS Y
WHERE Y.SEX="女")
(10)
SELECT SNAME, AGE
FROM S AS X
WHERE X.SEX="男" AND X.AGE>ALL
(SELECT AGE
FROM S AS Y
WHERE Y.SEX="女")
(11)
SELECT *
FROM S
WHERE S# IN
(SELECT S#
FROM SC
GROUP BY S# HAVING COUNT(S#)>
(SELECT COUNT(*)
FROM SC
WHERE S#="S0001"
)
)
(12)
SELECT S.S#, COUNT(S.S#) AS COUNT C, SUM(GRADE) AS TOTAL G
INTO RESULT
FROM S JOIN SC ON S.S#=SC. S#
GROUP BY S.S#
(13)
DELETE FROM SC
WHERE GRADE IS NULL
(14)
DELETE FROM SC
WHERE S# IN
(SELECT S#
FROM S
WHERE SNAME="张三")
(15)
UPDATE SC
SET GRADE=NULL
WHERE GRADE<60 AND C# IN
(SELECT C#
FROM C
WHERE CNAME="操作系统")
(16)
UPDATE SC
SET GRADE=GRADE*1.1
WHERE GRADE<(SELECT AVG(GRADE) FROM SC. AND
S# IN(SELECT S# FROM S WHERE SEX="女")
语法树
查询优化:先做选择,运用投影去除多余属性等等。语法树(尽量提前做选择操作;在每个操作后,应做个投影操作,去掉不用的属性值)。
:::info
- 构造查询树:
查询树是一种表示关系代数表达式的树形结构。
在一个查询树中,叶子结点表示关系,内结点表示关系代数操作。
查询树以自底向上的方式执行:当一个内结点的操作分量可用时,这个内结点所表示的操作启动执行,执行结束后用结果关系代替这个内结点。
- 优化查询树
- 利用等价转换规则反复地对查询表达式进行尝试性转换,将原始的语法树转換成“优化”的形式
- 对每一个选择,利用等价变换规则尽可能把它移到树的叶端。目的是使选择操作尽早执行
- 对每一个投影利用等价变换规则尽可能把它移向树的叶端。目的是使投影操作尽早执行
- 对每个叶节点加必要的投影操作,以消除对查询无用的属性。
- 如果笛卡尔乘积后还须按连接条件进行选择操作,可将两者组合成连接操作选择下沉,投影随后
:::
例题1