1. 程式人生 > 資料庫 >重溫《資料庫系統概論》【第一篇 基礎篇】【第3章 關係資料庫標準語言SQL】

重溫《資料庫系統概論》【第一篇 基礎篇】【第3章 關係資料庫標準語言SQL】

本篇內容為中國人民大學教授王珊、薩師煊的《資料庫系統概論》自學課程的複習筆記,學習視訊源於小破站(),對應視訊P16-P27,屬教材“【第一篇 基礎篇】”的“【第3章 關係資料庫標準語言SQL】”內容。

在這裡插入圖片描述

文章目錄


P16 SQL概述

在這裡插入圖片描述

16.1 SQL的特點

  1. 綜合統一
  2. 高度非過程化
  3. 面向集合的操作方式
  4. 以同一種語法結構提供多種使用方式
    ① SQL是獨立的語言
    ② SQL能嵌入到高階語言(例如:C、C++、Java)
  5. 語言簡潔,易學易用
    在這裡插入圖片描述

16.2 SQL的基本概念

  • 外模式包括若干檢視(view)和部分基本表(base table)
  • 模式包括若干基本表
  • 內模式包括若干儲存檔案(stored file)
    在這裡插入圖片描述

P17 資料定義

17.1 SQL的資料定義語句

  • 關係資料庫系統支援三級模式結構;
  • 其模式、外模式、內模式中的基本物件有模式、表、檢視和索引等;
  • SQL的資料定義功能包括模式定義、表定義、檢視和索引的定義
  • Tips:
    ① SQL標準不提供修改模式定義和修改檢視定義的操作,若想要修改則必須先刪除後重建。
    ② SQL標準也未提供索引相關語句,但為了提高查詢效率,商用關係資料庫管理系統通常都提供相應機制。
操作物件操作方式
建立刪除修改
模式CREATE SCHEMADROP SCHEMA
CREATE TABLEDROP TABLEALTER TABLE
檢視CREATE VIEWDROP VIEW
索引CREATE INDEXDROP INDEXALTER INDEX
  • 一個關係資料庫管理系統的例項中可以建立多個數據庫;
  • 一個數據庫可以建立多個模式;
  • 一個模式下通常包括多個表、檢視和索引等資料庫物件。
    在這裡插入圖片描述

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 <表名>;

在這裡插入圖片描述

  • 修改索引
ALTER INDEX <舊索引名> RENAME TO <新索引名>;
//【例】將SC表的SCno索引名改為SCSno

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

DROP INDEX Stusname;

P18 資料查詢-單表查詢

18.1 單表查詢語句格式

在這裡插入圖片描述

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區別
    在這裡插入圖片描述
  • 綜合練習
    在這裡插入圖片描述
    在這裡插入圖片描述

P20 資料查詢-連線查詢

20.1 等值與非等值連線查詢

  • 使用“=”為等值連線
  • 使用其他運算子為非等值連線
  • 相應方法
    ① 巢狀迴圈法:外表外迴圈掃描,內表內迴圈掃描;
    ② 排序合併法:先對兩張表排序,通過指標拼接相應元組;
    ③ 索引連線:通過索引直接定位查詢,效率最高。
// 查詢每個學生及其選修課程的情況

SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno = SC.sno;	//將Student與SC中同意學生的元組連線起來

在這裡插入圖片描述

20.2 自身連線(一個表與其自身的連線)

// 查詢每一門課的直接先修課的名稱

SELECT FIRST.Cname, SECOND.Cname	// 定義別名完成自身連線
FROM Course FIRST, Course SECOND
WHERE FIRST.Cpno = SECOND.Cno;

在這裡插入圖片描述
在這裡插入圖片描述

20.3 外連線(填補空值NULL)

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

在這裡插入圖片描述

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';		//<>不等於
=<>或!=<<=>>=
ANYIN<MAX<=MAX>MIN>=MIN
ALLNOT 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 語句的一般格式
在這裡插入圖片描述


P24 空值處理

  • 空值的產生、判斷(IS NULL 或 IS NOT NULL)
  • 空值的算術運算、比較運算和邏輯運算
  • 邏輯運算子真值表
    在這裡插入圖片描述

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 檢視的作用

在這裡插入圖片描述


札記

  • 資料庫安全審計系統提供了一種( 事前預測)的安全機制。
  • 把對關係SPJ的屬性QTY的修改權授予使用者李勇的T-SQL語句是( GRANT UPDATE ON SPJ (QTY) TO ‘李勇’ )。
  • 保護資料庫安全性的一般方法是( 設定使用者標識;存取許可權控制 )。
  • 安全性控制的一般方法有( 使用者標識鑑定;存取控制;審計;資料加密)。
  • 資料物件的範圍越小,授權子系統就越靈活。關於授權子系統,是DBMS中負責許可權管理的子系統,不是指授權物件。“靈活”是指可以進行更精細的存取控制