資料庫總結第三章
第三章 關係資料庫標準語言SQL
3.1 SQL概述
標準 |
大致頁數 |
釋出日期 |
SQL/86 |
1986.10 |
|
SQL/89(FIPS 127-1) |
120頁 |
1989年 |
SQL/92 |
622頁 |
1992年 |
SQL99(SQL 3) |
1700頁 |
1999年 |
SQL2003 |
3600頁 |
2003年 |
SQL2008 |
3777頁 |
2006年 |
SQL2011 |
2010年 |
SQL(Structured Query Language)
結構化查詢語言,是關係資料庫的標準語言
SQL是一個通用的、功能極強的關係資料庫語言
目前,沒有一個數據庫系統能夠支援SQL標準的所有概念和特性
3.1.2 SQL的特點
綜合統一
集資料定義語言(DDL),資料操縱語言(DML),資料控制語言(DCL)功能於一體。
可以獨立完成資料庫生命週期中的全部活動:
定義和修改、刪除關係模式,定義和刪除檢視,插入資料,建立資料庫;
對資料庫中的資料進行查詢和更新;
資料庫重構和維護
資料庫安全性、完整性控制,以及事務控制
嵌入式SQL和動態SQL定義
使用者資料庫投入執行後,可根據需要隨時逐步修改模式,不影響資料庫的執行。
資料操作符統一
非關係資料模型的資料操縱語言“面向過程”,必須指定存取路徑。
SQL只要提出“做什麼”,無須瞭解存取路徑。
存取路徑的選擇以及SQL的操作過程由系統自動完成。
非關係資料模型採用面向記錄的操作方式,操作物件是一條記錄
SQL採用集合操作方式
操作物件、查詢結果可以是元組的集合
一次插入、刪除、更新操作的物件可以是元組的集合
SQL是獨立的語言
能夠獨立地用於聯機互動的使用方式
SQL又是嵌入式語言
SQL能夠嵌入到高階語言(例如C,C++,Java)程式中,供程式設計師設計程式時使用
SQL功能極強,完成核心功能只用了9個動詞。
3.1.3 SQL的基本概念
SQL |
檢視2 |
檢視1 |
基本表2 |
基本表1 |
基本表3 |
基本表4 |
儲存檔案2 |
儲存檔案1 |
外模式 |
模 式 |
內模式 |
基本表
1,本身獨立存在的表
2,SQL中一個關係就對應一個基本表
3,一個(或多個)基本表對應一個儲存檔案
4,一個表可以帶若干索引
儲存檔案
1,邏輯結構組成了關係資料庫的內模式
2,物理結構對使用者是隱蔽的
檢視
1,從一個或幾個基本表匯出的表
2,資料庫中只存放檢視的定義而不存放檢視對應的資料
3,檢視是一個虛表
4,使用者可以在檢視上再定義檢視
資料定義
SQL的資料定義功能:
1,模式定義
2,表定義
3,檢視和索引的定義
現代關係資料庫管理系統提供了一個層次化的資料庫物件命名機制
1,一個關係資料庫管理系統的例項(Instance)中可以建立多個數據庫
2,一個數據庫中可以建立多個模式
3,一個模式下通常包括多個表、檢視和索引等資料庫物件
模式的定義與刪除
定義模式實際上定義了一個名稱空間。
在這個空間中可以定義該模式包含的資料庫物件,例如基本表、檢視、索引等。
在CREATE SCHEMA中可以接受CREATE TABLE,CREATE VIEW和GRANT子句。
CREATE SCHEMA <模式名> AUTHORIZATION <使用者名稱>[<表定義子句>|<檢視定義子句>|<授權定義子句>]
DROP SCHEMA <模式名> <CASCADE|RESTRICT>
CASCADE(級聯)
刪除模式的同時把該模式中所有的資料庫物件全部刪除
RESTRICT(限制)
如果該模式中定義了下屬的資料庫物件(如表、檢視等),則拒絕該刪除語句的執行。
僅當該模式中沒有任何下屬的物件時才能執行。
基本表的定義、刪除與修改
定義基本表
CREATE TABLE <表名>
(<列名> <資料型別>[ <列級完整性約束條件> ]
[,<列名> <資料型別>[ <列級完整性約束條件>] ]
…
[,<表級完整性約束條件> ] );
<表名>:所要定義的基本表的名字
<列名>:組成該表的各個屬性(列)
<列級完整性約束條件>:涉及相應屬性列的完整性約束條件
<表級完整性約束條件>:涉及一個或多個屬性列的完整性約束條件
如果完整性約束條件涉及到該表的多個屬性列,則必須定義在表級上,否則既可以定義在列級也可以定義在表級。
SQL中域的概念用資料型別來實現
定義表的屬性時需要指明其資料型別及長度
選用哪種資料型別
取值範圍
要做哪些運算
資料型別 |
含義 |
CHAR(n),CHARACTER(n) |
長度為n的定長字串 |
VARCHAR(n), CHARACTERVARYING(n) |
最大長度為n的變長字串 |
CLOB |
字串大物件 |
BLOB |
二進位制大物件 |
INT,INTEGER |
長整數(4位元組) |
SMALLINT |
短整數(2位元組) |
BIGINT |
大整數(8位元組) |
NUMERIC(p,d) |
定點數,由p位數字(不包括符號、小數點)組成,小數後面有d位數字 |
DECIMAL(p, d), DEC(p, d) |
同NUMERIC |
REAL |
取決於機器精度的單精度浮點數 |
DOUBLE PRECISION |
取決於機器精度的雙精度浮點數 |
FLOAT(n) |
可選精度的浮點數,精度至少為n位數字 |
BOOLEAN |
邏輯布林量 |
DATE |
日期,包含年、月、日,格式為YYYY-MM-DD |
TIME |
時間,包含一日的時、分、秒,格式為HH:MM:SS |
TIMESTAMP |
時間戳型別 |
INTERVAL |
時間間隔型別 |
每一個基本表都屬於某一個模式
一個模式包含多個基本表
定義基本表所屬模式
方法一:在表名中明顯地給出模式名
Create table"S-T".Student(......); /*模式名為 S-T*/
Create table "S-T".Cource(......);
Create table "S-T".SC(......);
方法二:在建立模式語句中同時建立表
方法三:設定所屬的模式
建立基本表(其他資料庫物件也一樣)時,若沒有指定模式,系統根據搜尋路徑來確定該物件所屬的模式
關係資料庫管理系統會使用模式列表中第一個存在的模式作為資料庫物件的模式名
若搜尋路徑中的模式名都不存在,系統將給出錯誤
顯示當前的搜尋路徑: SHOW search_path;
搜尋路徑的當前預設值是:$user, PUBLIC
資料庫管理員使用者可以設定搜尋路徑,然後定義基本表
SET search_path TO "S-T",PUBLIC;
Create table Student(......);
結果建立了S-T.Student基本表。
關係資料庫管理系統發現搜尋路徑中第一個模式名S-T,
就把該模式作為基本表Student所屬的模式。
ALTER TABLE <表名>
[ ADD[COLUMN] <新列名> <資料型別> [ 完整性約束 ] ]
[ ADD <表級完整性約束>]
[ DROP [ COLUMN ] <列名> [CASCADE| RESTRICT] ]
[ DROP CONSTRAINT<完整性約束名>[ RESTRICT | CASCADE ] ]
[ALTER COLUMN <列名><資料型別> ] ;
<表名>是要修改的基本表
ADD子句用於增加新列、新的列級完整性約束條件和新的表級完整性約束條件
DROP COLUMN子句用於刪除表中的列
如果指定了CASCADE短語,則自動刪除引用了該列的其他物件
如果指定了RESTRICT短語,則如果該列被其他物件引用,關係資料庫管理系統將拒絕刪除該列
DROP CONSTRAINT子句用於刪除指定的完整性約束條件
ALTER COLUMN子句用於修改原有的列定義,包括修改列名和資料型別
DROP TABLE <表名>[RESTRICT| CASCADE];
RESTRICT:刪除表是有限制的。
欲刪除的基本表不能被其他表的約束所引用
如果存在依賴該表的物件,則此表不能被刪除
CASCADE:刪除該表沒有限制。
在刪除基本表的同時,相關的依賴物件一起刪除
DROP TABLE時,SQL2011 與 3個RDBMS的處理策略比較
序 號 |
標準及主流資料庫 的處理方式 依賴基本表 的物件 |
SQL2011 |
Kingbase ES |
Oracle 12c |
MS SQL Server 2012 |
|||
R |
C |
R |
C |
C |
||||
1 |
索引 |
無規定 |
√ |
√ |
√ |
√ |
√ |
|
2 |
檢視 |
× |
√ |
× |
√ |
√ 保留 |
√ 保留 |
√ 保留 |
3 |
DEFAULT,PRIMARY KEY,CHECK(只含該表的列)NOT NULL 等約束 |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
4 |
外碼FOREIGN KEY |
× |
√ |
× |
√ |
× |
√ |
× |
5 |
觸發器TRIGGER |
× |
√ |
× |
√ |
√ |
√ |
√ |
6 |
函式或儲存過程 |
× |
√ |
√ 保留 |
√ 保留 |
√ 保留 |
√ 保留 |
√ 保留 |
索引的建立與刪除
建立索引的目的:加快查詢速度
關係資料庫管理系統中常見索引:
順序檔案上的索引
B+樹索引(http://www.chinadb.org/home/nav/5/sub/21/third/98/)
雜湊(hash)索引
點陣圖索引
特點:
B+樹索引具有動態平衡的優點
HASH索引具有查詢速度快的特點
誰可以建立索引
資料庫管理員 或 表的屬主(即建立表的人)
誰維護索引
關係資料庫管理系統自動完成
使用索引
關係資料庫管理系統自動選擇合適的索引作為存取路徑,使用者不必也不能顯式地選擇索引
語句格式
CREATE [UNIQUE] [CLUSTER] INDEX <索引名>
ON <表名>(<列名>[<次序>][,<列名>[<次序>] ]…);
<表名>:要建索引的基本表的名字
索引:可以建立在該表的一列或多列上,各列名之間用逗號分隔
<次序>:指定索引值的排列次序,升序:ASC,降序:DESC。預設值:ASC
UNIQUE:此索引的每一個索引值只對應唯一的資料記錄
CLUSTER:表示要建立的索引是聚簇索引
ALTER INDEX <舊索引名> RENAME TO <新索引名>
刪除索引時,系統會從資料字典中刪去有關該索引的
描述。
資料字典
資料字典是關係資料庫管理系統內部的一組系統表,它記錄了資料庫中所有定義資訊:
1,關係模式定義
2,檢視定義
3,索引定義
4,完整性約束定義
5,各類使用者對資料庫的操作許可權
6,統計資訊等
關係資料庫管理系統在執行SQL的資料定義語句時,實際上就是在更新資料字典表中的相應資訊。
資料查詢
語句格式
SELECT [ALL|DISTINCT] <目標列表達式>[,<目標列表達式>] …
FROM <表名或檢視名>[,<表名或檢視名> ]…|(SELECT 語句)
[AS]<別名>
[ WHERE <條件表示式> ]
[ GROUP BY <列名1> [ HAVING <條件表示式> ] ]
[ ORDER BY <列名2> [ ASC|DESC ] ];
SELECT子句:指定要顯示的屬性列
FROM子句:指定查詢物件(基本表或檢視)
WHERE子句:指定查詢條件
GROUP BY子句:對查詢結果按指定列的值分組,該屬性列值相等的元組為一個組。通常會在每組中作用聚集函式。
HAVING短語:只有滿足指定條件的組才予以輸出
ORDER BY子句:對查詢結果表按指定列值的升序或降序排序
3.4.1 單表查詢
查詢僅涉及一個表
1.選擇表中的若干列
2.選擇表中的若干元組
3.ORDER BY子句
4.聚集函式
5.GROUP BY子句
1,查詢指定列
[例3.16] 查詢全體學生的學號與姓名。
SELECT Sno,Sname
FROM Student;
[例3.17] 查詢全體學生的姓名、學號、所在系。
SELECT Sname,Sno,Sdept
FROM Student;
查詢全部列
選出所有屬性列:
在SELECT關鍵字後面列出所有列名
將<目標列表達式>指定為 *
查詢經過計算的值
SELECT子句的<目標列表達式>不僅可以為表中的屬性列,也可以是表示式
2,消除取值重複的行
如果沒有指定DISTINCT關鍵詞,則預設為ALL
指定DISTINCT關鍵詞,去掉表中重複的行
常用的查詢條件
查 詢 條 件 |
謂 詞 |
比 較 |
=, >, <, >=, <=, !=, <>, !>, !<; NOT+上述比較運算子 |
確定範圍 |
BETWEEN AND, NOT BETWEEN AND |
確定集合 |
IN, NOT IN |
字元匹配 |
LIKE, NOT LIKE |
空 值 |
IS NULL, IS NOT NULL |
多重條件(邏輯運算) |
AND, OR, NOT |
查 詢 條 件 |
謂 詞 |
比 較 |
=, >, <, >=, <=, !=, <>, !>, !<; NOT+上述比較運算子 |
確定範圍 |
BETWEEN AND, NOT BETWEEN AND |
確定集合 |
IN, NOT IN |
字元匹配 |
LIKE, NOT LIKE |
空 值 |
IS NULL, IS NOT NULL |
多重條件(邏輯運算) |
AND, OR, NOT |
謂詞: BETWEEN … AND …
NOT BETWEEN … AND …
謂詞:IN <值表>, NOT IN <值表>
謂詞: [NOT] LIKE ‘<匹配串>’ [ESCAPE ‘ <換碼字元>’]
匹配串為固定字串
匹配串為含萬用字元的字串
使用換碼字元將萬用字元轉義為普通字元
謂詞: IS NULL 或 IS NOT NULL
“IS” 不能用 “=” 代替
邏輯運算子:AND和 OR來連線多個查詢條件
AND的優先順序高於OR
可以用括號改變優先順序
3,ORDER BY子句
可以按一個或多個屬性列排序
升序:ASC;降序:DESC;預設值為升序
對於空值,排序時顯示的次序由具體系統實現來決定
4,聚集函式
聚集函式:
統計元組個數
COUNT(*)
統計一列中值的個數
COUNT([DISTINCT|ALL] <列名>)
計算一列值的總和(此列必須為數值型)
SUM([DISTINCT|ALL] <列名>)
計算一列值的平均值(此列必須為數值型)
AVG([DISTINCT|ALL] <列名>)
求一列中的最大值和最小值
MAX([DISTINCT|ALL] <列名>)
MIN([DISTINCT|ALL] <列名>)
5.GROUP BY子句
GROUP BY子句分組:
細化聚集函式的作用物件
如果未對查詢結果分組,聚集函式將作用於整個查詢結果
對查詢結果分組後,聚集函式將分別作用於每個組
按指定的一列或多列值分組,值相等的為一組
HAVING短語與WHERE子句的區別:
作用物件不同
WHERE子句作用於基表或檢視,從中選擇滿足條件的元組
HAVING短語作用於組,從中選擇滿足條件的組。
3.4.2 連線查詢
連線查詢:同時涉及兩個以上的表的查詢
連線條件或連線謂詞:用來連線兩個表的條件
一般格式:
[<表名1>.]<列名1> <比較運算子> [<表名2>.]<列名2>
[<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>
連線欄位:連線謂詞中的列名稱
連線條件中的各連線欄位型別必須是可比的,但名字不必相同
連線查詢:同時涉及兩個以上的表的查詢
連線條件或連線謂詞:用來連線兩個表的條件
一般格式:
[<表名1>.]<列名1> <比較運算子> [<表名2>.]<列名2>
[<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>
連線欄位:連線謂詞中的列名稱
連線條件中的各連線欄位型別必須是可比的,但名字不必相同
1.等值與非等值連線查詢
(1)巢狀迴圈法(NESTED-LOOP)
首先在表1中找到第一個元組,然後從頭開始掃描表2,逐一查詢滿足連線件的元組,找到後就將表1中的第一個元組與該元組拼接起來,形成結果表中一個元組。
表2全部查詢完後,再找表1中第二個元組,然後再從頭開始掃描表2,逐一查詢滿足連線條件的元組,找到後就將表1中的第二個元組與該元組拼接起來,形成結果表中一個元組。
重複上述操作,直到表1中的全部元組都處理完畢
(2)排序合併法(SORT-MERGE)
常用於=連線
首先按連線屬性對錶1和表2排序
對錶1的第一個元組,從頭開始掃描表2,順序查詢滿足連線條件的元組,找到後就將表1中的第一個元組與該元組拼接起來,形成結果表中一個元組。當遇到表2中第一條大於表1連線欄位值的元組時,對錶2的查詢不再繼續
找到表1的第二條元組,然後從剛才的中斷點處繼續順序掃描表2,查詢滿足連線條件的元組,找到後就將表1中的第一個元組與該元組拼接起來,形成結果表中一個元組。直接遇到表2中大於表1連線欄位值的元組時,對錶2的查詢不再繼續
重複上述操作,直到表1或表2中的全部元組都處理完畢為止
(3)索引連線(INDEX-JOIN)
對錶2按連線欄位建立索引
對錶1中的每個元組,依次根據其連線欄位值查詢表2的索引,從中找到滿足條件的元組,找到後就將表1中的第一個元組與該元組拼接起來,形成結果表中一個元組
一條SQL語句可以同時完成選擇和連線查詢,這時WHERE子句是由連線謂詞和選擇謂片語成的複合條件。
2.自身連線
自身連線:一個表與其自己進行連線
需要給表起別名以示區別
由於所有屬性名都是同名屬性,因此必須使用別名字首
3.外連線
外連線與普通連線的區別
普通連線操作只輸出滿足連線條件的元組
外連線操作以指定表為連線主體,將主體表中不滿足連線條件的元組一併輸出
左外連線
列出左邊關係中所有的元組
右外連線
列出右邊關係中所有的元組
4.多表連線
多表連線:兩個以上的表進行連線
3.4.3 巢狀查詢
巢狀查詢概述
一個SELECT-FROM-WHERE語句稱為一個查詢塊
將一個查詢塊巢狀在另一個查詢塊的WHERE子句或HAVING短語的條件中的查詢稱為巢狀查詢
SELECT Sname /*外層查詢/父查詢*/
FROM Student
WHERE Sno IN
( SELECT Sno /*內層查詢/子查詢*/
FROM SC
WHERE Cno= ' 2 ');
上層的查詢塊稱為外層查詢或父查詢
下層查詢塊稱為內層查詢或子查詢
SQL語言允許多層巢狀查詢
即一個子查詢中還可以巢狀其他子查詢
子查詢的限制
不能使用ORDER BY子句
不相關子查詢:
子查詢的查詢條件不依賴於父查詢
由裡向外 逐層處理。即每個子查詢在上一級查詢處理之前求解,子查詢的結果用於建立其父查詢的查詢條件。
相關子查詢:子查詢的查詢條件依賴於父查詢
首先取外層查詢中表的第一個元組,根據它與內層查詢相關的屬性值處理內層查詢,若WHERE子句返回值為真,則取此元組放入結果表
然後再取外層表的下一個元組
重複這一過程,直至外層表全部檢查完為止
1.帶有IN謂詞的子查詢
查詢與“劉晨”在同一個系學習的學生。
此查詢要求可以分步來完成
① 確定“劉晨”所在系名
SELECT Sdept
FROM Student
WHERE Sname= ' 劉晨 ';
結果為: CS
2.帶有比較運算子的子查詢
當能確切知道內層查詢返回單值時,可用比較運算子(>,<,=,>=,<=,!=或< >)。
在[例 3.55]中,由於一個學生只可能在一個系學習,則可以用 = 代替IN :
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept =
(SELECT Sdept
FROM Student
WHERE Sname= '劉晨');
可能的執行過程
從外層查詢中取出SC的一個元組x,將元組x的Sno值(201215121)傳送給內層查詢。
SELECT AVG(Grade)
FROM SC y
WHERE y.Sno='201215121‘;
執行內層查詢,得到值88(近似值),用該值代替內層查詢,得到外層查詢:
SELECT Sno,Cno
FROM SC x
WHERE Grade >=88;
3.帶有ANY(SOME)或ALL謂詞的子查詢
使用ANY或ALL謂詞時必須同時使用比較運算
語義為:
> ANY 大於子查詢結果中的某個值
> ALL 大於子查詢結果中的所有值
< ANY 小於子查詢結果中的某個值
< ALL 小於子查詢結果中的所有值
>= ANY 大於等於子查詢結果中的某個值
>= ALL 大於等於子查詢結果中的所有值
使用ANY或ALL謂詞時必須同時使用比較運算
語義為(續)
<= ANY 小於等於子查詢結果中的某個值
<= ALL 小於等於子查