《數(shù)據(jù)庫(kù)系統(tǒng)概論》筆記 3 -- SQL 基本功能

3.1 SQL 概述

3.1.1 SQL 的特點(diǎn)

  1. 綜合統(tǒng)一

將數(shù)據(jù)定義語(yǔ)言(DML)、數(shù)據(jù)查詢語(yǔ)言(DQL)崖咨、數(shù)據(jù)操縱語(yǔ)言(DML)、數(shù)據(jù)控制語(yǔ)言(DCL)集合在一起,語(yǔ)言風(fēng)格統(tǒng)一嵌莉。

  1. 高度非過(guò)程化

菲關(guān)系數(shù)據(jù)模型的數(shù)據(jù)操縱語(yǔ)言是“面向過(guò)程”的語(yǔ)言,“過(guò)程化”語(yǔ)言完成某項(xiàng)請(qǐng)求必須指定存取路徑捻脖。SQL 只需要用戶指出做什么锐峭,無(wú)需指明怎么做,存取路徑對(duì)用戶透明可婶。

  1. 面向集合的操作方式

更新操作(插入沿癞、刪除、修改)的對(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ì)視圖查詢的步驟:

  1. 首先進(jìn)行有效性檢查都伪,檢查查詢中涉及的表呕乎、視圖是否存在;
  2. 如果存在陨晶,則從數(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 視圖的作用

  1. 視圖能夠簡(jiǎn)化用戶的操作

通過(guò)定義視圖能夠使數(shù)據(jù)庫(kù)看起來(lái)結(jié)構(gòu)簡(jiǎn)單、清晰硅蹦。使用戶只需要關(guān)注需要關(guān)注的數(shù)據(jù)荣德。

  1. 視圖使用戶能以多種角度看待同一數(shù)據(jù)

如年齡信息闷煤,有些用戶看到的是年齡,有些則可以看到出生年份涮瞻。

  1. 為重構(gòu)數(shù)據(jù)庫(kù)提供一定的邏輯獨(dú)立性

定義視圖可以在基本表增加新的字段或結(jié)構(gòu)變化時(shí)鲤拿,不會(huì)改變視圖看到的內(nèi)容,從而不必更改應(yīng)用程序署咽,提高了邏輯獨(dú)立性近顷。

  1. 對(duì)機(jī)密數(shù)據(jù)提供安全保護(hù)
  2. 更簡(jiǎn)潔地表達(dá)查詢
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市艇抠,隨后出現(xiàn)的幾起案子幕庐,更是在濱河造成了極大的恐慌,老刑警劉巖家淤,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件异剥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡絮重,警方通過(guò)查閱死者的電腦和手機(jī)冤寿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)青伤,“玉大人督怜,你說(shuō)我怎么就攤上這事『萁牵” “怎么了号杠?”我有些...
    開(kāi)封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)丰歌。 經(jīng)常有香客問(wèn)我姨蟋,道長(zhǎng),這世上最難降的妖魔是什么立帖? 我笑而不...
    開(kāi)封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任眼溶,我火速辦了婚禮,結(jié)果婚禮上晓勇,老公的妹妹穿的比我還像新娘堂飞。我一直安慰自己,他們只是感情好绑咱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布绰筛。 她就那樣靜靜地躺著,像睡著了一般描融。 火紅的嫁衣襯著肌膚如雪铝噩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天稼稿,我揣著相機(jī)與錄音薄榛,去河邊找鬼讳窟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛敞恋,可吹牛的內(nèi)容都是我干的丽啡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼硬猫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼补箍!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起啸蜜,我...
    開(kāi)封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坑雅,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后衬横,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體裹粤,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年蜂林,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遥诉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡噪叙,死狀恐怖咆爽,靈堂內(nèi)的尸體忽然破棺而出怠缸,到底是詐尸還是另有隱情揣炕,我是刑警寧澤族阅,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站子眶,受9級(jí)特大地震影響瀑凝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜壹店,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一猜丹、第九天 我趴在偏房一處隱蔽的房頂上張望芝加。 院中可真熱鬧硅卢,春花似錦、人聲如沸藏杖。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蝌麸。三九已至点寥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間来吩,已是汗流浹背敢辩。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工蔽莱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人戚长。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓盗冷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親同廉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仪糖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容