3.1 SQL 概述
3.1.1 SQL 的特點(diǎn)
- 綜合統(tǒng)一
將數(shù)據(jù)定義語(yǔ)言(DML)、數(shù)據(jù)查詢語(yǔ)言(DQL)崖咨、數(shù)據(jù)操縱語(yǔ)言(DML)、數(shù)據(jù)控制語(yǔ)言(DCL)集合在一起,語(yǔ)言風(fēng)格統(tǒng)一嵌莉。
- 高度非過(guò)程化
菲關(guān)系數(shù)據(jù)模型的數(shù)據(jù)操縱語(yǔ)言是“面向過(guò)程”的語(yǔ)言,“過(guò)程化”語(yǔ)言完成某項(xiàng)請(qǐng)求必須指定存取路徑捻脖。SQL 只需要用戶指出做什么锐峭,無(wú)需指明怎么做,存取路徑對(duì)用戶透明可婶。
- 面向集合的操作方式
更新操作(插入沿癞、刪除、修改)的對(duì)象和查找操作的對(duì)象都可以是元組的集合矛渴,而不僅僅是一條記錄椎扬。
3.1.2 SQL 的基本概念
SQL 的功能動(dòng)詞表
SQL 功能 | 動(dòng)詞 |
---|---|
數(shù)據(jù)查詢 | SELECT |
數(shù)據(jù)定義 | CREATE,DROP具温,ALTER |
數(shù)據(jù)操縱 | INSERT蚕涤,UPDATE,DELETE |
數(shù)據(jù)控制 | GRANT铣猩,REVOKE |
支持 SQL 的關(guān)系數(shù)據(jù)庫(kù)支持三級(jí)模式結(jié)構(gòu)揖铜。外模式包括視圖和部分基本表,數(shù)據(jù)庫(kù)模式包括若干基本表达皿,內(nèi)模式包括若干存儲(chǔ)文件天吓。
3.2 數(shù)據(jù)定義
SQL 的數(shù)據(jù)定義語(yǔ)句
操作對(duì)象 | 創(chuàng)建 | 刪除 | 修改 |
---|---|---|---|
模式 | CREATE SCHEMA | DROP SCHEMA | |
表 | CREATE TABLE | DROP TABLE | ALTER TABLE |
視圖 | CREATE VIEW | DROP VIEW | |
索引 | CREATE INDEX | DROP INDEX | ALTER INDEX |
SQL 標(biāo)準(zhǔn)中不提供修改模式定義和視圖定義的操作贿肩,只能先刪除再重建。
SQL 標(biāo)準(zhǔn)沒(méi)有索引相關(guān)語(yǔ)句龄寞,商用關(guān)系數(shù)據(jù)庫(kù)通常提供汰规。
關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)可以創(chuàng)建多個(gè)數(shù)據(jù)庫(kù),一個(gè)數(shù)據(jù)庫(kù)可以有多個(gè)模式(多個(gè)命名空間)物邑,一個(gè)模式下通常包括多個(gè)基本表溜哮、視圖和索引等數(shù)據(jù)庫(kù)對(duì)象。
在 MySQL 中創(chuàng)建的模式(schema)與數(shù)據(jù)庫(kù)(database)等價(jià)拂封,也就是可以有多個(gè)數(shù)據(jù)庫(kù)茬射,每個(gè)對(duì)應(yīng)一個(gè)模式。
3.2.1 模式的定義與刪除
1 定義模式
CREATE SCHEMA <模式名> AUTHORIZATION <用戶名>;
如果沒(méi)有指定 <模式名>冒签,那么 <模式名> 隱含為 <用戶名>在抛。
定義模式實(shí)際上定義了一個(gè)命名空間,在這個(gè)空間中可以進(jìn)一步定義該模式包含的對(duì)象萧恕,如基本表刚梭、視圖、索引票唆。
SQL 語(yǔ)句不區(qū)分大小寫朴读。
MySQL 中的不同點(diǎn):
- 不支持授權(quán)用戶語(yǔ)句 AUTHORIZATION <用戶名>。
- 可以將 SCHEMA 替換為 DATABASE走趋。
2 刪除模式
DROP SCHEMA <模式名> <CASCADE|RESTRICT>;
CASCADE 和 RESTRICT 二者必選其一衅金。前者為級(jí)聯(lián),表示刪除模式包含的所有數(shù)據(jù)庫(kù)對(duì)象簿煌;后者表示限制氮唯,當(dāng)包含對(duì)象。
MySQL 中的不同點(diǎn):
- 刪除方式默認(rèn)為級(jí)聯(lián)姨伟,語(yǔ)句中不能使用 <CASCADE|RESTRICT>惩琉。
3 切換模式(MySQL)
在 MySQL 中,可以使用 USE 切換到其他模式SCHEMA(或數(shù)據(jù)庫(kù) DATABASE):
USE others;
3.2.2 基本表的定義夺荒、刪除與修改
1 定義基本表
CREATE TABLE <表名>(<列名> <數(shù)據(jù)類型> [列級(jí)完整性約束條件]
[,<列名> <數(shù)據(jù)類型> [列級(jí)完整性約束條件]]
...
[,表級(jí)完整性約束條件]);
完整性約束條件涉及多個(gè)屬性列瞒渠,必須定義在表級(jí),否則表級(jí)和列級(jí)皆可技扼。
可以通過(guò)查詢結(jié)果創(chuàng)建新的表:
CREATE TABLE
AS
<子查詢語(yǔ)句>;
2 修改基本表
ALTER TABLE <表名>
[ADD [COLUMN] <新列名> <數(shù)據(jù)類型> [列級(jí)完整性約束]]
[,ADD <表級(jí)完整性約束>]
[,DROP [COLUMN] <列名> [CASCADE|RESTRICT]] # 如果有其他對(duì)象引用該列伍玖,CASCADE 會(huì)刪除引用他的對(duì)象,RESTRICT 會(huì)拒絕刪除操作剿吻。
[,DROP CONSTRAINT <完整性約束名> [RESTRICT|CASCADE]]
[,ALTER COLUMN <列名> <數(shù)據(jù)類型>];
同一類修改語(yǔ)句可以同時(shí)執(zhí)行多次窍箍,用逗號(hào)隔開(kāi)。
MySQL 的不同點(diǎn):
- 不允許修改原有的列定義。
- 修改列信息改為:CHANGE <原列名> <新列名> <數(shù)據(jù)類型>仔燕。
3 刪除基本表
DROP TABLE <表名> [CASCADE|RESTRICT]; # 如果該表中列被其他表的約束引用,或存在視圖魔招、觸發(fā)器等晰搀,CASCADE 會(huì)刪除相關(guān)對(duì)象,RESTRICT 會(huì)拒絕刪除操作办斑。
1.2.3 索引的建立外恕、修改與刪除
1 建立索引
CREATE [UNIQUE] [CLUSTER] INDEX <索引名> # UNIQUE 代表每個(gè)索引對(duì)應(yīng)唯一元組。
ON <表名>(<列名> [<次序>] [,<列名> [<次序>]]...);
2 修改索引
ALTER INDEX <舊索引名> RENAME TO <新索引名>;
MySQL 的不同點(diǎn):
- 不支持修改索引乡翅。
3 刪除索引
DROP INDEX <索引名> ON <表名>; # SQL 語(yǔ)言中不加表名鳞疲,MySQL 必須加。
3.2.4 數(shù)據(jù)字典
數(shù)據(jù)字典是數(shù)據(jù)庫(kù)管理系統(tǒng)內(nèi)部的一組表蠕蚜,記錄了數(shù)據(jù)庫(kù)中所有的定義信息尚洽,包括關(guān)系模式定義、視圖定義靶累、索引定義腺毫、完整性約束定義、操作權(quán)限挣柬、統(tǒng)計(jì)信息等潮酒。
3.3 數(shù)據(jù)查詢
SELECT [ALL|DISTINCT] <目標(biāo)列表表達(dá)式>[,<目標(biāo)列表表達(dá)式>]...
FROM <表明或視圖名> [別名][,<表明或視圖名> [別名]...]|(<SELECT語(yǔ)句>) [AS] <別名>
[WHERE <條件表達(dá)式>]
[GROUP BY <列名1>[,<列名1>] [HAVING <條件表達(dá)式>]] # HAVING 子句必須與 GROUP BY 同時(shí)出現(xiàn)。
[ORDER BY <列名2> [ASC|DESC][,<列名2> [ASC|DESC]...]];
根據(jù) WHERE 子句中的條件表達(dá)式從 FROM 子句指定的基本表邪蛔、視圖或派生表中找出滿足條件的元組急黎,再按 SELECT 子句中的目標(biāo)列表達(dá)式選出元組中的屬性值形成結(jié)果表。
如果沒(méi)有 WHERE 子句侧到,則選出關(guān)系中所有元組勃教。
如果GROUP BY 子句,則按<列名 1>的值進(jìn)行分組床牧,該屬性列相等的元組為一個(gè)組荣回。通常會(huì)對(duì)每組作用聚集函數(shù)。如果還帶有 HAVING 短語(yǔ)戈咳,則只有滿足指定條件的組予以輸出心软。
如果有 ORDER BY 子句,則結(jié)果表按<列名 2>的值的升序或降序排序著蛙。
3.3.1 單表查詢
單表查詢是指僅涉及一個(gè)表的查詢删铃。
1 選擇表中的若干列
選擇表中的全部或部分列即投影運(yùn)算。
# 查詢指定列踏堡,目標(biāo)列的順序可以不與表中的順序一致猎唁。
SELECT Sno,Sname
FROM Student;
# 查詢?nèi)苛校部梢詫⒘忻苛谐觥?SELECT *
FROM Student;
# 查詢經(jīng)過(guò)計(jì)算的值顷蟆,<目標(biāo)列表達(dá)式>不僅可以是屬性列诫隅,還可以是表達(dá)式腐魂。
SELECT Sname,2014-Sage
FROM Student;
# <目標(biāo)列表達(dá)式>不僅可以是算數(shù)表達(dá)式,還可以是字符串常量逐纬、函數(shù)等蛔屹。
SELECT 'Year of Birthday',LOWER(Sdept)
FROM Student;
# 可以通過(guò)指定別名改變查詢的列標(biāo)題
SELECT Sname NAME
FROM Student;
2 選擇結(jié)果表中的若干元組
兩個(gè)本來(lái)不完全相同的元組投影到指定的某些列上后,可能變成相同的行豁生,可以通過(guò) DISTICT 消除重復(fù)行兔毒。不指定 DISTINCT 關(guān)鍵詞則默認(rèn)為 ALL,保留重復(fù)行甸箱。
# 消除取值重復(fù)的行育叁。
SELECT DISTINCT Sno
FROM SC;
# 以下兩種等價(jià)。
SELECT Sno
FROM SC;
SELECT ALL Sno
FROM SC;
可以通過(guò) WHERE 子句查找滿足指定條件的元組芍殖。
常用的查詢條件
查詢條件 | 謂詞 |
---|---|
比較 | =豪嗽,>,<豌骏,>=昵骤,<=,<>(!=) |
確定范圍 | BETWEEN AND肯适,NOT BETWEEN AND |
確定集合 | IN变秦,NOT IN |
字符匹配 | LIKE,NOT LIKE |
空值 | IS NULL框舔,IS NOT NULL |
多重條件(邏輯運(yùn)算) | AND蹦玫,OR,NOT(置于條件表達(dá)式前部刘绣,AND優(yōu)先級(jí)大于OR樱溉,可以使用括號(hào)調(diào)整優(yōu)先級(jí)) |
字符匹配的語(yǔ)法:
% 代表任意長(zhǎng)度(長(zhǎng)度可以為0)的字符串。
_ 代表任意單個(gè)字符纬凤。
如果要查詢的字符串中本來(lái)就含有通配符福贞,需要指定一個(gè)換碼字符對(duì)通配符進(jìn)行轉(zhuǎn)義,使用 [ESCAPE'<換碼字符>'] 短語(yǔ)停士。
3 ORDER BY 子句
可以用 ORDER BY 子句對(duì)查詢結(jié)果按照一個(gè)或多個(gè)屬性列的升序(ASC)或降序(DESC)排列挖帘,默認(rèn)為升序,優(yōu)先按照前面的列排序恋技。
4 聚集函數(shù)
聚集函數(shù) | 功能 |
---|---|
COUNT(*) | 統(tǒng)計(jì)元組個(gè)數(shù) |
COUNT([DISDINCT|ALL] <列名>) | 統(tǒng)計(jì)一列中值的個(gè)數(shù) |
SUM([DISDINCT|ALL] <列名>) | 計(jì)算一列值的總和(刺裂必須為數(shù)值型) |
AVG([DISDINCT|ALL] <列名>) | 計(jì)算一列值的平均值(此列必須為數(shù)值型) |
MAX([DISDINCT|ALL] <列名>) | 求一列值中的最大值 |
MIN([DISDINCT|ALL] <列名>) | 求一列值中的最小值 |
使用聚集函數(shù)的注意事項(xiàng):
- 如果指定 DISTINCT 短語(yǔ)拇舀,計(jì)算時(shí)會(huì)取消指定列中的重復(fù)值。如果不指定 DISDINCT 短語(yǔ)或指定 ALL 短語(yǔ)(ALL為默認(rèn)值)蜻底,則不取消重復(fù)值骄崩。
- 聚集函數(shù)遇到空值時(shí),都會(huì)跳過(guò)空值。而COUNT()或者COUNT(任意數(shù)值或字符串)都是統(tǒng)計(jì)元組個(gè)數(shù)要拂,不會(huì)跳過(guò)空值抠璃。某列或部分列取空值*不會(huì)影響 COUNT 的統(tǒng)計(jì)結(jié)果。
- WHERE 子句中不能使用聚集函數(shù)作為條件表達(dá)式脱惰。聚集函數(shù)只能用于 SELECT 子句和 GROUP BY 中的 HAVING 子句鸡典。
5 GROUP BY 子句
GROUP BY 子句將查詢結(jié)果按某列或多列(列名之間用逗號(hào)隔開(kāi))的值分組,值相等的為一組枪芒。
注意事項(xiàng):
- HAVING 短語(yǔ)作用于分組之后。
- 聚集函數(shù)作用在每個(gè)分組上谁尸。
WHERE 子句與 HAVING 短語(yǔ)的區(qū)別在于作用對(duì)象不同舅踪。WHERE 子句作用于基本表或視圖,從中選擇滿足條件的元組良蛮。HAVING 短語(yǔ)作用于組抽碌,從中選擇滿足條件的組。
3.3.2 連接查詢
1 等值與非等值連接查詢
連接查詢的 WHERE 子句中用來(lái)連接兩個(gè)表的條件稱為連接條件或連接謂詞决瞳,一般格式為:
? [<表名1>.] <列名1> <比較運(yùn)算符> [<表名2>.] <列名2>
其中比較運(yùn)算符主要=货徙、>、<皮胡、>=痴颊、<=、!=(或<>)等屡贺。
還可以使用:
? [<表名1>.] <列名1> BETWEEN [<表名2>.] <列名2> AND [<表名2>.] <列名3>
連接運(yùn)算符為 = 時(shí)蠢棱,稱為等值連接,其余為非等值連接甩栈。
連接謂詞中的列名稱為連接字段泻仙。各字段類型必須是可比的,但名字不必相同量没。
在等值連接時(shí)把目標(biāo)列中重復(fù)的屬性列去掉玉转,變?yōu)?strong>自然連接。
SELECT Student.Sno,Sname,Ssex,Sdept,Cno,Grade # 屬性列名稱唯一的可以省略表名前綴殴蹄,在兩個(gè)表中均出現(xiàn)時(shí)究抓,必須加上表名前綴。
FROM Student,SC
WHERE Student.Sno=SC.Sno;
2 自身連接
連接操作不僅可以在兩個(gè)表之間進(jìn)行袭灯,也可以是一個(gè)表與自己進(jìn)行連接漩蟆。
# 查詢每一門課的間接先修課
SELECT FIRST.Cno,SECOND.Cpro
FROM SC FIRST,SC SECOND
WHERE FIRST.Cpro=SECOND.Cno;
3 外連接
可以使用 <表名1> LEFT OUTER JOIN <表名2> ON (<表名1>.<列名>=<表名2>.<列名>) 實(shí)現(xiàn)左外連接。
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUTER JOIN SC ON (Student.Sno=SC.Sno);
可以使用 USING 去掉重復(fù)值妓蛮,這種情況下可以省略表名前綴怠李。
SELECT Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUTER JOIN SC USING(Sno);
同時(shí)可以使用 INNER JOIN 實(shí)現(xiàn)內(nèi)連接。
SELECT Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student INNER JOIN SC USING(Sno);
4 多表連接
除了兩表連接和自身連接,還可以通過(guò)邏輯運(yùn)算符實(shí)現(xiàn)多表連接捺癞。
3.3.3 嵌套查詢
在 SQL 語(yǔ)言中夷蚊,一個(gè) SELECT-FROM-WHERE 語(yǔ)句稱為一個(gè)查詢塊。將一個(gè)查詢塊嵌套在另一個(gè)查詢塊的 WHERE 或 HAVING 的條件中的查詢稱為嵌套查詢髓介。
SELECT Sname
FROM Student
WHERE Sno IN
(SELECT Sno
FROM SC
WHERE Cno'2');
上層的查詢塊稱為外層查詢或父查詢惕鼓,下層的查詢塊稱為內(nèi)層查詢或子查詢。
注意事項(xiàng):
- 允許子查詢嵌套子查詢唐础,實(shí)現(xiàn)多層嵌套查詢箱歧。
- 子查詢的 SELECT 語(yǔ)句中不能使用 ORDER BY 子句,ORDER BY 子句只能對(duì)最終查詢結(jié)果排序一膨。
1 帶 IN 謂詞的子查詢
子查詢的結(jié)果通常是一個(gè)集合呀邢,可以使用 IN 謂詞。
SELECT Sno,Sname
FROM Student
WHERE Sno IN
(SELECT Sno
FROM SC
WHERE Cno IN
(SELECT Cno
FROM Course
WHERE Cname='信息系統(tǒng)')
);
這種嵌套查詢可以使用連接運(yùn)算代替豹绪。
SELECT Student.Sno,Sname
FROM Student,SC,Course
WHERE Student.Sno=SC.Sno AND
SC.Cno=Course.Cno AND
Course.Cname='信息系統(tǒng)';
能夠使用連接運(yùn)算符表達(dá)的查詢盡可能采用連接運(yùn)算价淌。
上例中子查詢的查詢條件不依賴父查詢,稱為不相關(guān)子查詢瞒津。
2 帶有比較運(yùn)算符的子查詢
帶有比較運(yùn)算符的子查詢是指父查詢與子查詢之間用比較運(yùn)算符連接蝉衣。當(dāng)確定子查詢返回單個(gè)值時(shí),可以使用比較運(yùn)算符巷蚪。
# 找出每個(gè)學(xué)生超過(guò)他自己選修課程平均分的課程號(hào)病毡。
SELECT Sno,Cno
FROM SC x
WHERE Grade>=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
這種子查詢的查詢條件與父查詢相關(guān)的,稱為相關(guān)子查詢屁柏。
3 帶有 ANY(SOME)或 ALL 謂詞的子查詢
當(dāng)子查詢返回多值時(shí)剪验,同時(shí)使用比較運(yùn)算符和 ANY 或 ALL。
其語(yǔ)義為與返回值的任一(ANY)或所有(ALL)比較都滿足則為真前联,否則為假功戚。
# 查詢非CS系比CS系的任意一個(gè)學(xué)生年齡小的學(xué)生姓名和年齡
SELECT Snam,Sage
FROM Student
WHERE Sage<ANY(SELECT Sage
FROM Student
WHERE Sdept='CS');
# 其語(yǔ)義相當(dāng)于比結(jié)果中最大的小即可。
SELECT Snam,Sage
FROM Student
WHERE Sage<(SELECT MAX(Sage)
FROM Student
WHERE Sdept='CS');
用聚集函數(shù)實(shí)現(xiàn)子查詢通常比 ANY 或 ALL 查詢效率高似嗤。
4 帶有 EXIST 謂詞的子查詢
EXIST 代表存在謂詞啸臀。帶有 EXIST 謂詞的子查詢不返回?cái)?shù)據(jù),只產(chǎn)生邏輯真 “true” 或邏輯假 “false” 烁落。
# 查詢所有選修了1號(hào)課程的學(xué)生姓名乘粒。
SELECT Sname
FROM Student
WHERE EXIST(SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='1');
由于 EXIST 謂詞只返回真假值,列名無(wú)意義伤塌,所以通常使用 * 灯萍。
SQL 中沒(méi)有全稱量詞,但可以使用存在謂詞嵌套達(dá)到同樣的效果每聪。
# 查詢選修全部課程的學(xué)生名稱旦棉,相當(dāng)于沒(méi)有一門課沒(méi)有選擇齿风。
SELECT Sname
FROM Student
WHERE NOT EXIST(SELECT *
FROM Course
WHERE NOT EXIST(SELECT *
FROM SC
WHERE Student.Sno=Sno AND Course.Cno=Cno)
);
3.3.4 集合查詢
SELECT 查詢的結(jié)果是元組的集合,可以對(duì)多個(gè) SELECT 語(yǔ)句的結(jié)果進(jìn)行集合操作绑洛。集合操作主要包括并 UNION救斑、交 INTERSECT、差 EXCEPT真屯。
進(jìn)行集合操作的各查詢結(jié)果列數(shù)和對(duì)應(yīng)項(xiàng)的數(shù)據(jù)類型必須相同脸候。
# 查詢選修了1號(hào)或者2號(hào)課程的學(xué)生。
SELECT Sno
FROM SC
WHERE Cno='1' # 注意這里沒(méi)有分號(hào)
UNION
SELECT Sno
FROM SC
WHERE Cno='2';
3.3.5 基于派生表的查詢
子查詢不僅可以出現(xiàn)在 WHERE 子句中绑蔫,還可以出現(xiàn)在 FROM 子句中运沦,這時(shí)子查詢會(huì)生成臨時(shí)派生表作為子查詢的對(duì)象。
# 查詢課程成績(jī)比選課平均成績(jī)高的學(xué)生學(xué)號(hào)和課程配深。
SELECT Sno,Cno
FROM SC,(SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno) AS Avg_sc(avg_sno,avg_grade)
WHERE SC.Sno=avg_sno AND SC.grade>=Avg_sc.avg_grade;
3.4 數(shù)據(jù)更新
3.4.1 插入數(shù)據(jù)
插入語(yǔ)句 INSERT 有兩種形式携添,一種插入元組,一種插入子查詢結(jié)果凉馆,后者一次可以插入多個(gè)元組。
1 插入元組
INSERT INTO <表名> [(<屬性列1>[,<屬性列2>]...)]
VALUES(<常量1>[,<常量2>]...)
注意事項(xiàng):
- INTO 子句中沒(méi)有出現(xiàn)的屬性列取自動(dòng)取空值亡资。
- INTO 子句中沒(méi)有指明任何屬性列名澜共,則插入的新元組必須在每個(gè)屬性列上均有值,且順序與表中一致锥腻。
- 屬性列名可以和表中的順序不一致嗦董,但需要和 VALUES 中的對(duì)應(yīng),即數(shù)據(jù)類型必須滿足屬性列名的要求瘦黑。
2 插入子查詢結(jié)果
INSERT INTO <表名> [(<屬性列1>[,<屬性列2>]...)]
子查詢;
3.4.2 修改數(shù)據(jù)
UPDATE <表名>
SET <列名>=<表達(dá)式>[,<列名>=<表達(dá)式>...]
[WHERE <條件>];
注意事項(xiàng):
- 修改滿足 WHERE 子句條件的元組值京革,未指定條件則修改所有元組值。
- WHERE 子句中同樣可以嵌套子查詢幸斥。
3.4.3 刪除數(shù)據(jù)
DELETE
FROM <表名>
[WHERE <條件>];
注意事項(xiàng):
- 如果未指定 WHERE 子句中的條件匹摇,會(huì)刪除所有元組,但表的定義仍在數(shù)據(jù)字典中甲葬。
3.5 視圖
視圖是從一個(gè)或幾個(gè)基本表(或視圖)導(dǎo)出的表廊勃。數(shù)據(jù)庫(kù)中只存放視圖的定義,不存放視圖的數(shù)據(jù)经窖。
3.5.1 視圖的建立與刪除
要想修改視圖坡垫,只能通過(guò)刪除重建。
1 建立視圖
CREATE VIEW <視圖名> [(<列名>[,<列名>...])]
AS <子查詢>
[WITH CHECK OPTION];
注意事項(xiàng):
- 子查詢可以為任意的 SELECT 子句画侣。
- WHERE CHECK OPTION 表示對(duì)視圖進(jìn)行 UPDATE冰悠、INSERT 和 DELETE 操作時(shí)要保證被修改的行滿足視圖定義中的謂詞條件。
- 組成視圖的屬性列名必須全部指定或全部省略(用 SELECT 子句中的字段名組成)配乱,如下情況必須指定列名:
- 某個(gè)目標(biāo)列是聚集函數(shù)或列表達(dá)式溉卓;
- 多表連接時(shí)選出同名列作為視圖字段皮迟;
- 需啟用更合適的名字。
# 建立信息系學(xué)生的視圖的诵,并且修改時(shí)需保證該視圖只有信息系學(xué)生万栅。
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS'
WITH CHECK OPTION;
當(dāng)視圖從單個(gè)基本表導(dǎo)出,并且去掉了某些行和列西疤,但保留了主碼烦粒,則成為行列子集視圖。
視圖可以建立在一個(gè)或多個(gè)表代赁。
# 建立信息系選修了1號(hào)課程的學(xué)生的視圖(包括學(xué)號(hào)扰她、姓名、成績(jī))芭碍。
CREATE VIEW IS_S1(Sno,Sname,Grade)
AS
SELECT Student.Sno,Sname,Grade
FROM Student,SC
WHERE Student.Sno=SC.Sno AND Sdept='IS' AND Cno='1';
視圖可以建立在一個(gè)或多個(gè)定義好的視圖徒役。
# 建立信息系選修了一號(hào)課程且成績(jī)?cè)?0分以上的學(xué)生的視圖。
CREATE VIEW IS_S2
AS
SELECT Sno,Sname,Grade
FROM IS_S1
WHERE Grade>=90;
定義視圖時(shí)需要根據(jù)應(yīng)用需求設(shè)置一些派生屬性列窖壕,由于這些屬性列不實(shí)際存在忧勿,稱為虛擬列,也稱為帶表達(dá)式的視圖瞻讽。
# 定義一個(gè)反映學(xué)生出生年份的視圖鸳吸。
CREATE VIEW BT_S(Sno,Sname,Sbirth) # 由于使用
AS
SELECT Sno,Sname,2020-Sage
FROM Student;
還可以用帶聚集函數(shù)和 GROUP BY 子句的查詢定義視圖,稱為分組視圖速勇。
# 按學(xué)生的學(xué)號(hào)及平時(shí)成績(jī)定義為一個(gè)視圖晌砾。
CREATE VIEW S_G(Sno,Gavg) # 由于使用聚集函數(shù),屬性列名必須明確定義烦磁。
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
2 刪除視圖
DROP VIEW <視圖名> [CASCADE];
將視圖定義從數(shù)據(jù)字典中刪除养匈。使用 CASCADE 短語(yǔ)可以級(jí)聯(lián)刪除在該視圖上導(dǎo)出的視圖。
3.5.2 查詢視圖
對(duì)視圖查詢的步驟:
- 首先進(jìn)行有效性檢查都伪,檢查查詢中涉及的表呕乎、視圖是否存在;
- 如果存在陨晶,則從數(shù)據(jù)字典中取出視圖的定義楣嘁,把定義中的子查詢和用戶查詢結(jié)合起來(lái),轉(zhuǎn)換成等價(jià)的對(duì)基本表的查詢珍逸,再執(zhí)行修正后的查詢逐虚。這一過(guò)程稱為視圖消解。
有些視圖查詢?cè)谀承╆P(guān)系數(shù)據(jù)庫(kù)系統(tǒng)中是不一定能進(jìn)行轉(zhuǎn)換的谆膳,對(duì)于這種視圖查詢通常直接在基本表上進(jìn)行叭爱。
# 查詢平均分視圖上對(duì)平均成績(jī)?cè)?0分以上的學(xué)生學(xué)號(hào)和平均成績(jī)。
SELECT *
FROM S_G
WHERE Gavg>=90;
# 轉(zhuǎn)換后漱病。
SELECT Sno,AVG(Grade)
FROM SC
WHERE AVG(Grade)>=90
GROUP BY Sno;
# 由于 WHERE 子句中不能使用聚集函數(shù)买雾,所以轉(zhuǎn)換錯(cuò)誤把曼,正確轉(zhuǎn)換為。
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
3.5.3 更新視圖
更新視圖是通過(guò)視圖來(lái)增刪改數(shù)據(jù)漓穿。
基本操作與基本表上類似嗤军。但需要注意的是,如果在定義視圖時(shí)晃危,沒(méi)有添加 WITH CHECK OPTION 子句叙赚,則有可能影響到視圖范圍外的數(shù)據(jù)。
下面創(chuàng)建四種視圖
# 對(duì)于包含專業(yè)項(xiàng)的視圖僚饭,在WHERE條件表達(dá)式中可以判斷專業(yè)信息為其他專業(yè)震叮,如:WHERE Sdept='MA'
# 視圖中包含專業(yè)項(xiàng),但沒(méi)有 WITH CHECK OPTION 子句鳍鸵。
# UPDATE 時(shí)可以將專業(yè)數(shù)據(jù)改成其他專業(yè)苇瓣。
# INSERT 時(shí)可以插入其他專業(yè)學(xué)生的信息。
# DELETE 不受影響偿乖。
CREATE VIEW IS_CS
AS
SELECT Sname,Sdept
FROM Student
WHERE Sdept='CS';
# 視圖中不包含專業(yè)項(xiàng)击罪,但沒(méi)有 WITH CHECK OPTION 子句。
# UPDATE贪薪、INSERT媳禁、DELETE 均不受影響。
CREATE VIEW IS_CS
AS
SELECT Sname
FROM Student
WHERE Sdept='CS';
# 視圖中包含專業(yè)項(xiàng)古掏,但有 WITH CHECK OPTION 子句损话。
# UPDATE 時(shí)拒絕將專業(yè)數(shù)據(jù)改成其他專業(yè)侦啸。
# INSERT 時(shí)只能插入該該專業(yè)的學(xué)生信息槽唾,插入其他專業(yè)時(shí)拒絕。
# DELETE 不受影響光涂。
CREATE VIEW IS_CS
AS
SELECT Sname,Sdept
FROM Student
WHERE Sdept='CS'
WITH CHECK OPTION;
# 視圖中不包含專業(yè)項(xiàng)庞萍,但有 WITH CHECK OPTION 子句。
# INSERT 時(shí)無(wú)法插入任何學(xué)生信息忘闻,因?yàn)镾dept缺省钝计,自動(dòng)設(shè)置為NULL。
# UPDATE 和 DELETE 不受影響齐佳。
CREATE VIEW IS_CS
AS
SELECT Sname
FROM Student
WHERE Sdept='CS'
WITH CHECK OPTION;
另外私恬,不是所有的視圖都可以更新,有些視圖的更新不能唯一有意義地轉(zhuǎn)化成相應(yīng)基本表的更新炼吴。
# 對(duì)這種視圖中的Gavg屬性值進(jìn)行修改時(shí)是無(wú)效的本鸣。
CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
3.5.4 視圖的作用
- 視圖能夠簡(jiǎn)化用戶的操作
通過(guò)定義視圖能夠使數(shù)據(jù)庫(kù)看起來(lái)結(jié)構(gòu)簡(jiǎn)單、清晰硅蹦。使用戶只需要關(guān)注需要關(guān)注的數(shù)據(jù)荣德。
- 視圖使用戶能以多種角度看待同一數(shù)據(jù)
如年齡信息闷煤,有些用戶看到的是年齡,有些則可以看到出生年份涮瞻。
- 為重構(gòu)數(shù)據(jù)庫(kù)提供一定的邏輯獨(dú)立性
定義視圖可以在基本表增加新的字段或結(jié)構(gòu)變化時(shí)鲤拿,不會(huì)改變視圖看到的內(nèi)容,從而不必更改應(yīng)用程序署咽,提高了邏輯獨(dú)立性近顷。
- 對(duì)機(jī)密數(shù)據(jù)提供安全保護(hù)
- 更簡(jiǎn)潔地表達(dá)查詢