重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

本篇内容为中国人民大学教授王珊、萨师煊的《数据库系统概论》自学课程的复习笔记,学习视频源于小破站(传送门),对应视频P16-P27,属教材“【第一篇 基础篇】”的“【第3章 关系数据库标准语言SQL】”内容。

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

文章目录


P16 SQL概述

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

16.1 SQL的特点

  1. 综合统一
  2. 高度非过程化
  3. 面向集合的操作方式
  4. 以同一种语法结构提供多种使用方式
    ① SQL是独立的语言
    ② SQL能嵌入到高级语言(例如:C、C++、Java)
  5. 语言简洁,易学易用
    重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

16.2 SQL的基本概念

  • 外模式包括若干视图(view)和部分基本表(base table)
  • 模式包括若干基本表
  • 内模式包括若干存储文件(stored file)
    重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

P17 数据定义

17.1 SQL的数据定义语句

  • 关系数据库系统支持三级模式结构;
  • 其模式、外模式、内模式中的基本对象有模式、表、视图和索引等;
  • SQL的数据定义功能包括模式定义、表定义、视图和索引的定义
  • Tips:
    ① SQL标准不提供修改模式定义和修改视图定义的操作,若想要修改则必须先删除后重建。
    ② SQL标准也未提供索引相关语句,但为了提高查询效率,商用关系数据库管理系统通常都提供相应机制。
操作对象 操作方式
创建 删除 修改
模式 CREATE SCHEMA DROP SCHEMA
CREATE TABLE DROP TABLE ALTER TABLE
视图 CREATE VIEW DROP VIEW
索引 CREATE INDEX DROP INDEX ALTER INDEX
  • 一个关系数据库管理系统的实例中可以建立多个数据库;
  • 一个数据库可以建立多个模式;
  • 一个模式下通常包括多个表、视图和索引等数据库对象。
    重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

17.2 模式的定义与删除

  • 定义模式
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>

要创建模式,调用该命令的用户必须拥有数据库管理员权限,或者获得了数据库管理员授予的 CREATE SCHEMA 的权限。

//【例】为用户ZHANG创建一个模式TEST,并且在其中定义一个表TAB1

CREATE SCHEMA TEST AUTHORIZATION ZHANG
CREATE TABLE TAB1(COL1 SMALLINT,
				  COL2 INT,
				  COL3 CHAR(20),
				  COL4 NUMERIC(10,3),
				  COL5 DECIMAL(5,2),
				  );
  • 删除模式
    ① CASCADE 和 RESTRICT 两者必选其一。
    ② CASCADE(级联):删除模式的同时把该模式中所有数据库对象全部删除。【危险性较高,谨慎使用!!!】
    ③ RESTRICT(限制):若模式中已经定义了下属的数据库对象(如表、视图等),则拒绝该删除语句的执行;只有当该模式没有任何下属对象时才能执行 DROP 语句。
DROP SCHEMA <模式名> <CASCADE|RESTRICT>
//【例】删除模式ZHANG,同时,该模式中已经定的一TAB1也被删除(级联方式删除模式)

DROP SCHEMA ZHANG CASCADE;

17.3 基本表的定义、删除与修改

  • 定义基本表
//【例】建立一个“学生”表Student

CREATE TABLE Student
	(Sno CHAR(9) PRIMARY KEY,	// Sno为主键
	Sname CHAR(20) UNIQUE,		// Sname取唯一值
	Ssex CHAR(2),
	Sage SMALLINT,
	Sdept CHAR(20),
	);							// 注意逗号和分号


//【例】建立一个“课程”表Course

CREATE TABLE Course
	(Cno CHAR(4) PRIMARY KEY,	// Cno为主键
	Cname CHAR(40) NOT NULL,	// Cname非空
	Cpno CHAR(4),				// Cpno为为先行课
	Credit SMALLINT,
	FOREIGN KEY (Cpno) REFERENCES Course(Cno),
	);							// Cpno为外码,被参照表是Course,被参照列是Cno


//【例】建立学生选课表SC

CREATE TABLE SC
	(Sno CHAR(9),
	Cno CHAR(4),
	Grade SMALLINT,
	PRIMARY KEY (Sno, Cno),						// 主码由两个属性构成
	FOREIGN KEY (Sno) REFERENCES Student(Sno),	// Sno是外码,被参照表是Student
	FOREIGN KEY (Cno) REFERENCES Course(Cno),	// Cno是外码,被参照表是Course
	);
  • 修改基本表
ALTER TABLE<表名>
[ADD [COLUMN] <新列名><数据类型>]
[DROP [COLUMN] <列名> [CASCADE|RESTRICT]]
[ALTER COLUMN <列名><数据类型>];
//【例】向Student表增加“入学时间”列,其数据类型为日期型

ALTER TABLE Student ADD S_entrence DATE;


//【例】将年龄的数据类型由字符型改为整数

ALTER TABLE Student ALTER COLUMN Sage INT;


//【例】增加课程名称必须取唯一值的约束条件

ALTER TABLE Course ADD UNIQUE(Cname);

  • 删除基本表
DROP TABLE <表名> [CASCADE|RESTRICT];
//【例】删除Student表

DROP TABLE Student CASCADE;

17.4 索引的建立与删除

  • 建立索引
    当表的数据量比较大时,查询效率低耗时长,建立索引是加快查询速度的有效手段。常见数据库索引包括顺序文件上的索引、B+树索引、散列(hash)索引、位图索引。
    ① 顺序文件上的索引:属性值升 / 降序存储,指针操作。
    ② B+树索引:B+树叶结点指针存储,具有动态平衡的优点。
    ③ 散列(hash)索引:利用散列函数映射到若干个桶中存储,具有快速查找的优点。
    ④ 位图索引:位向量记录缩阴属性,每个位向量对应一个可能值。
CREATE [UNIQUE] [CLUSTER] INDEX <索引名> ON <表名>;

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

  • 修改索引
ALTER INDEX <旧索引名> RENAME TO <新索引名>;
//【例】将SC表的SCno索引名改为SCSno

ALTER INDEX SCno RENAME TO SCSno;
  • 删除索引
DROP INDEX <索引名>;
//【例】删除Student表的Stusname索引

DROP INDEX Stusname;

P18 数据查询-单表查询

18.1 单表查询语句格式

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

18.2 SELECT、 FROM、WHERE 子句

  • 选择表中若干列
// 【单列】查询全体学生的学号与姓名

SELECT Sno, Sname
FROM Student;


// 【部分列】查询全体学生的姓名、学号、所在系

SELECT Sname, Sno, Sdept
FROM Student;


// 【全部列】查询全部列

//等价于SELECT Sno, Sname, Ssex, Sage, Sdept
SELECT*
FROM Student;


// 【算术表达式】查询全体学生的姓名及其出生年份

SELECT Sname, 2020-Sage	// 表达式2020-Sage为出生年份
FROM Student;


// 【字符串常量、函数】查询全体学生的姓名、出生年份和所在的院系,要求用小写字母表示系名

SELECT Sname, 'Year of Birth:', 2020-Sage, LOWER(Sdept)	// 'Year of Birth' 再建一列, LOWER小写字母
FROM Studen;


// 【定义别名】

SELECT Sname NAME, 'Year of Birth:' BIRTH, 2020-Sage BIRTHDAY, LOWER(Sdept) DEPARTMENT
FROM Student;

  • 选择表中若干元组
    ① 消除取值重复行 DISTINCT
    ② 查询满足条件的元组 WHERE
查询条件 谓语
比较 =, >, <, >=, <=, <>, !>, !<, NOT+上述比较运算符
确定范围 BETWEEN AND, NOT BETWEEN AND
确定集合 IN, NOT IN
字符匹配 LIKE, NOT LIKE
空值 IS NULL, IS NOT NULL
多重条件(逻辑运算) AND, OR, NOT
// 【DISTINCT消除重复项】查询选修了课程的学生学号

SELECT DISTINCT Sno
FROM SC;


// 【WHERE比较大小<=>】
// 查询计算机科学系全体学生的名单

SELECT Sname
FROM Student
WHERE Sdept = 'SC';

// 查询所有年龄在20岁以下的学生姓名及其年龄

SELECT Sname, Sage
FROM Student
WHERE Sage < 20;

// 查询考试成绩不及格的学生的学号

SELECT DISTINCT Sno		// 后做数据库输出
FROM SC
WHERE Grade < 60;		// 先做WHERE条件查询


// 【WHERE确定范围BETWEEN……AND……】
// 查询年龄在20-23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄

SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;	// BETWEEN……AND……包头包尾:20、21、22、23

// 查询年龄不在20-23岁之间的学生的姓名、系别和年龄

SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;


// 【WHERE确定集合IN】
// 查询计算机科学系(CS)、数学系(MA)和信息系(IS)学生的姓名 和性别

SELECT Sname, Ssex
FROM Student
WHERE Sdept IN ('CS', 'MA', 'IS');


// 【WHERE字符匹配】
// %(百分号):表示任意长度的字符串
// _(下划线):表示任意单个字符

// 查询学号为201215121的学生的详细情况

SELECT *
FROM Student
WHERE Sno LIKE '201215121';

// 查询所有姓“张”的学生的姓名、学号和性别

SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname LIKE '张%';

// 查询姓“欧阳”且全名为三个汉字的学生的姓名

SELECT Sname
FROM Student
WHERE Sname LIKE '欧阳_';

// 查询名字中第二个字为“阳”的学生的姓名和学号

SELECT Sname, Sno
FROM Student
WHERE Sname LIKE '_阳%';

// 查询DB_Design课程的课程号和学分

SELECT Cno, Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design' ESCAPE '\';	//ESCAPE为转义操作'\'

// 【WHERE空值】
// 查询缺少成绩的学生的学号和相应的课程号

SELECT Sno, Cno
FROM SC
WHERE Grade IS NULL;	// 分数为空

// 查询所有有成绩的学生的学号和相应的课程号

SELECT Sno, Cno
FROM SC
WHERE Grade IS NOT NULL;	// 分数为空


// 【WHERE多重条件】
// 查询计算机科学系年龄在20岁以下的学生姓名

SELECT Sname
FROM Student
WHERE Sdept='CS' AND Sage<20; 


P19 数据查询-单表查询2

19.1 ORDER BY 子句

  • ORDER BY 子句
    ① ASC 升序
    ② DESC 降序
// 查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序排列

SELECT Sno, Grade
FROM SC
WHERE Cno = '3'
ORDER BY Grade DESC;

// 查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列

SELECT *
FROM Student
ORDER BY Sdept ASC, Sage DESC;

  • 聚集函数
    为增强检索功能,SQL提供了很多聚集函数,主要有:
函数 用途
COUNT(*) 统计元组个数
COUNT( [ DISTINCT | ALL]<列名> ) 统计一列中值的个数
SUM( [ DISTINCT | ALL]<列名> ) 计算一列值的总和(数值型)
AVG( [ DISTINCT | ALL]<列名> ) 计算一列值的平均值(数值型)
MAX( [ DISTINCT | ALL]<列名> ) 计算一列值的最大值
MIN( [ DISTINCT | ALL]<列名> ) 计算一列值的最小值
// 查询学生总人数

SELECT COUNT(*)
FROM Student;

// 查询选修了课程的学生人数
SELECT COUNT(DISTINCT Sno)
FROM SC;

// 计算选修1号课程的学生平均成绩
SELECT AVG(Grade)
FROM SC
WHERE Cno='1';

// 查询学生201215012选修课程的总学分数

SELECT SUM(Ccredit)
FROM SC, Course
WHERE Sno='201215012' AND SC.cno=Course.cno;

19.2 GROUP BY 子句

  • GROUP BY子句.
    分组:细化聚集函数的作用的对象。分组后聚集函数将作用于每一组,每一组都有一个函数值。
// 求各个课程号及相应的选课人数

SELECT Cno, COUNT(Sno)
FROM SC
GROUP BY Cno;

// 查询选修了三门以上课程的学生学号

SELECT Sno
FROM SC
GROUP BY Sno		// 先按照学号分组
HAVING COUNT(*)>3;	// 聚集函数统计每一组数量

// 查询平均成绩大于等于90分的学生学号和平均成绩

SELECT Sno, AVG(Grade)
FROM SC
GROUP BY Sno			// 先按照学号分组
HAVING AVG(Grade)>=90;	// 后计算平均值
  • HAVING与WHERE区别
    重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】
  • 综合练习
    重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】
    重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

P20 数据查询-连接查询

20.1 等值与非等值连接查询

  • 使用“=”为等值连接
  • 使用其他运算符为非等值连接
  • 相应方法
    ① 嵌套循环法:外表外循环扫描,内表内循环扫描;
    ② 排序合并法:先对两张表排序,通过指针拼接相应元组;
    ③ 索引连接:通过索引直接定位查询,效率最高。
// 查询每个学生及其选修课程的情况

SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno = SC.sno;	//将Student与SC中同意学生的元组连接起来

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

20.2 自身连接(一个表与其自身的连接)

// 查询每一门课的直接先修课的名称

SELECT FIRST.Cname, SECOND.Cname	// 定义别名完成自身连接
FROM Course FIRST, Course SECOND
WHERE FIRST.Cpno = SECOND.Cno;

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】
重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

20.3 外连接(填补空值NULL)

SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade
FROM Student LEFT OUTER JOIN SC ON (Student.Sno=SC.Sno);

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

20.4 多表连接(两个以上的表的连接)

// 查询每个学生的学号、姓名、选修的课程名及成绩

SELECT Student.Sno, Sname, Cname, Grade
FROM Student, SC, Course
WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno;

P21 数据查询-嵌套查询(≈套娃)

  • 一个SELECT-FROM-WHERE语句称为一个查询块
  • 上层查询块:外层查询或父查询
  • 下层查询块:内层查询或子查询
  • ORDER BY 子句只能对最终结果排序,故子循环中不可存在 ORDER BY 子句

21.1 带有 IN 谓词的子查询

// 查询与“刘晨”在同一个系学习的学生

// 第一步
SELECT Sdept
FROM Student
WHERE Sname='刘晨';
// 第二步
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept='CS'

// 合并一下套娃嵌套

SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept IN
	(SELECT Sdept
	 FROM Student
	 WHERE Sname='刘晨';)

21.2 带有比较运算符的子查询

// 找出每个学生超过他自己选修课程平均成绩的课程号

SELECT Sno, Cno
FROM SC x							// x为SC的别名
WHERE Grade >= (SELECT AVG(Grade)
				FROM SC y			// y为SC的别名
				WHERE y.Sno=x.Sno);

P22 数据查询-嵌套查询2

22.1 带有 ANY(SOME)或 ALL 谓词的子查询

// 查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄

SELECT Sname, Sage
FROM Student
WHERE Sage < ANY(SELECT Sage
				 FROM Student
				 WHERE Sdept='CS')
AND Sdept<>'CS';		//<>不等于
= <>或!= < <= > >=
ANY IN <MAX <=MAX >MIN >=MIN
ALL NOT IN <MIN <=MIN >MAX >=MAX

22.2 带有 EXISITS 谓词的子查询(≈存在)

// 查询所有选修了1号课程的学生姓名

SELECT Sname
FROM Student
WHERE EXISTS
	(SELECT *
	 FROM SC
	 WHERE Sno = Student.Sno AND Cno = '1');

P23 数据查询-集合查询

23.1 集合查询

操作 符号
并操作 UNION
交操作 INTERSECT
差操作 EXCEPT
// 查询计算机科学系的学生及年龄不大于19岁的学生

SELECT *
FROM Student
WHERE Sdept = 'CS'
UNION
SELECT *
FROM Student
WHERE Sage <= 19;


// 查询计算机科学系的学生与年龄不大于19岁的学生的交集

SELECT *
FROM Student
WHERE Sdept = 'CS'
INTERSECT
SELECT *
FROM Student
WHERE Sage <= 19;


// 查询计算机科学系的学生与年龄不大于19岁的学生的差集
// 即:查询计算机科学系中年龄大于19岁的学生

SELECT *
FROM Student
WHERE Sdept = 'CS'
EXCEPT
SELECT *
FROM Student
WHERE Sage <= 19;

23.2 查询语句小结

SELECT 语句的一般格式
重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】


P24 空值处理

  • 空值的产生、判断(IS NULL 或 IS NOT NULL)
  • 空值的算术运算、比较运算和逻辑运算
  • 逻辑运算符真值表
    重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】

P25 数据更新

25.1 插入语句

  • 插入元组
INSERT
INTO <表名> [(<属性列 1> [,<属性列2>] ……)]
VALUES (<常量 1> [,<常量 2> ……]);
// 将一个新学生元组插入到Student表中

INSERT
INTO Student (Sno, Sname, Ssex, Sdept, Sage)
VALUES ('201215128', '陈冬', '男', 'IS', '18');


// 将学生张成民的信息插入到Student表中

INSERT
INTO Student
VALUES ('201215126', '张成民', '男', '18', 'CS');	// 应与表中信息顺序一致


// 插入一条选课记录('201215128', '1')

INSERT
INTO SC (Sno, Cno)
VALUES ('201215128', '1');	// 未赋值则SC表中的Grade列自动赋为空值

INSERT
INTO SC
VALUES ('201215128', '1', NULL);
  • 插入子查询结果
INSERT
INTO <表名> [(<属性列 1> [,<属性列2>] ……)]
子查询;
// 对每一个系,求学生的平均年龄,并把结果存入数据库

CREATE TABLE Dept_age		// 首先先建立一个新表
	(Sdept CHAR(15)
	 AVG_age SMALLINT);

INSERT						// 最后插入新表
INTO Dept_age (Sdept, AVG_age)
SELECT Sdept, AVG(Sage)		// 其次按系分组求均值
FROM Student
GROUP BY Sdept;

25.2 修改语句

UPDATE <表名>
SET <列表>=<表达式> [,<列名>=<表达式>] ……
[WHERE <条件>];
// 将学生201215121的年龄改为22岁

UPDATE Student
SET Sage = '22'
WHERE Sno = '201215121';


// 将所有学生年龄都增加1岁

UPDATE Student
SET Sage = Sage + 1;


// 将计算机科学系学生全体学生的成绩置零

UPDATE SC
SET Grade = 0
WHERE Sno IN
	(SELECT Sno
	 FROM Student
	 WHERE Sdept = 'CS');

25.3 删除语句

DELETE
FROM <表名>
[WHERE <条件>];
// 删除学号为201215128的学生记录
DELETE 
FROM Student
WHERE Sno='201215128';


// 删除所有学生选课记录
DELETE 
FROM SC;


// 删除计算机科学系所有学生选课记录
DELETE 
FROM SC
WHERE Sno IN
	(SELECT Sno
	 FROM Student
	 WHERE Sdept = 'CS');

P26 视图

  • 视图是一种虚拟的表

26.1 定义视图

  • 建立视图
CREATE VIEW <视图名> [(<列名> [,<列名>]……)]
AS <子查询>
[WITH CHECK OPTION];
  • 删除视图
DROP VIEW <视图名> [CASCADE];

26.2 查询视图


P27 视图2

27.1 更新视图

27.2 视图的作用

重温《数据库系统概论》【第一篇 基础篇】【第3章 关系数据库标准语言SQL】


札记

  • 数据库安全审计系统提供了一种( 事前预测)的安全机制。
  • 把对关系SPJ的属性QTY的修改权授予用户李勇的T-SQL语句是( GRANT UPDATE ON SPJ (QTY) TO ‘李勇’ )。
  • 保护数据库安全性的一般方法是( 设置用户标识;存取权限控制 )。
  • 安全性控制的一般方法有( 用户标识鉴定;存取控制;审计;数据加密)。
  • 数据对象的范围越小,授权子系统就越灵活。关于授权子系统,是DBMS中负责权限管理的子系统,不是指授权对象。“灵活”是指可以进行更精细的存取控制
上一篇:sql语句,死磕_02


下一篇:Java笔记——类和对象