《數(shù)據(jù)庫原理與應(yīng)用》課件第3章_第1頁
《數(shù)據(jù)庫原理與應(yīng)用》課件第3章_第2頁
《數(shù)據(jù)庫原理與應(yīng)用》課件第3章_第3頁
《數(shù)據(jù)庫原理與應(yīng)用》課件第3章_第4頁
《數(shù)據(jù)庫原理與應(yīng)用》課件第3章_第5頁
已閱讀5頁,還剩337頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第3章關(guān)系數(shù)據(jù)庫與SQL語言

3.1關(guān)系數(shù)據(jù)庫的結(jié)構(gòu)3.2關(guān)系代數(shù)3.3擴展的關(guān)系代數(shù)3.4數(shù)據(jù)庫的修改操作3.5SQL3.6查詢優(yōu)化技術(shù)習(xí)題關(guān)系模型是目前最重要的一種數(shù)據(jù)模型。關(guān)系數(shù)據(jù)庫系統(tǒng)是以關(guān)系模型作為數(shù)據(jù)組織、管理方式的數(shù)據(jù)庫管理系統(tǒng)。1970年美國IBM公司SanJose研究室的研究員E.F.Codd首次提出了關(guān)系模型,開創(chuàng)了數(shù)據(jù)庫關(guān)系方法和關(guān)系代數(shù)理論的研究領(lǐng)域,為關(guān)系數(shù)據(jù)庫技術(shù)奠定了理論基礎(chǔ)。

20世紀80年代以來,計算機軟件廠商紛紛推出各自的數(shù)據(jù)庫管理系統(tǒng),其中涌現(xiàn)出許多性能良好的商用關(guān)系數(shù)據(jù)庫管理系統(tǒng)(簡稱RDBMS),如著名的SQLServer、DB2、Oracle、Ingres、Sybase和Informix等關(guān)系數(shù)據(jù)庫管理系統(tǒng)。隨著關(guān)系數(shù)據(jù)庫管理系統(tǒng)的發(fā)展和成熟,數(shù)據(jù)庫的應(yīng)用領(lǐng)域迅速擴大??梢哉f,目前所有主流的數(shù)據(jù)庫應(yīng)用領(lǐng)域都離不開關(guān)系數(shù)據(jù)庫管理系統(tǒng),而非關(guān)系模型的數(shù)據(jù)庫管理系統(tǒng)的產(chǎn)品也大都支持關(guān)系模型或擴展關(guān)系模型。本章先學(xué)習(xí)關(guān)系模型的理論基礎(chǔ),了解關(guān)系模型的數(shù)據(jù)表示方法;然后介紹關(guān)系數(shù)據(jù)庫查詢語言。3.1關(guān)系數(shù)據(jù)庫的結(jié)構(gòu)在關(guān)系模型中,無論是實體還是實體之間的聯(lián)系均由單一的結(jié)構(gòu)類型——關(guān)系(表)來表示。關(guān)系模型是建立在關(guān)系代數(shù)基礎(chǔ)上的面向集合操作的數(shù)據(jù)模型,這里將從集合論角度給出關(guān)系模型的形式化定義。關(guān)系數(shù)據(jù)庫是若干表的集合,每個表有唯一的名字。表的每一行數(shù)據(jù)代表現(xiàn)實世界的一個實體或者一個關(guān)聯(lián)。一個表就是一個實體集或一個關(guān)聯(lián)集。3.1.1基本關(guān)系結(jié)構(gòu)首先通過一個超市銷售系統(tǒng)的實例介紹關(guān)系模型。表3.1給出了超市銷售系統(tǒng)的“營業(yè)員”表,其中存放所有營業(yè)員的信息。該表有3列:工號、姓名和出生年月,每一列稱為一個屬性。每個屬性對應(yīng)一個定義取值范圍的集合,稱為該屬性的域。例如,屬性“姓名”的域是長度為4個漢字的字符串的集合。如果用D1表示營業(yè)員工號的域,用D2表示營業(yè)員姓名的域,用D3表示營業(yè)員出生年月的域?!盃I業(yè)員”表的每一行都是一個三元組(v1,v2,v3),其中v1是營業(yè)員工號(v1在域D1中),v2是營業(yè)員姓名(v2在域D2中),v3是營業(yè)員出生年月(v3在域D3中)。通常,一個超市銷售系統(tǒng)的“營業(yè)員”表是集合D1×D2×D3的一個有實際意義的子集。一般地說,有n個屬性的表是D1×D2×…×Dn-1×?Dn的一個子集,D1×?D2×…×Dn-1×Dn在數(shù)學(xué)上定義為域D1、D2、…、Dn-1、Dn上的笛卡爾積。關(guān)系就是定義在一系列域上的笛卡爾積的子集。可見,表實際上就是關(guān)系,因此可以用數(shù)學(xué)名詞關(guān)系和元組來代替表和行?!盃I業(yè)員”表也可以稱為“營業(yè)員”關(guān)系。元組變量就是代表元組的變量,即存放關(guān)系的一個元組的變量。表3.1“營業(yè)員”表如表3.1所示,“營業(yè)員”關(guān)系中共有8個元組。設(shè)元組變量t指向關(guān)系中的第一個元組,那么t?[工號]?表示t在“工號”屬性上的值。當前t?[工號]?的值是“001”,t?[姓名]?的值是“金文”。也可以用t?[1]?來表示元組t的第一個屬性(工號)上的值,t?[2]?表示元組t的第二個屬性上的值,等等。因為關(guān)系是元組的集合,所以可以用數(shù)學(xué)上tR表示元組t在關(guān)系R中。由于關(guān)系是元組的集合,所以元組在關(guān)系中出現(xiàn)的順序是無關(guān)緊要的。表3.2和表3.1所表示的關(guān)系是一樣的,因為它們是包含相同元組的集。表3.2具有無序元組的“營業(yè)員”關(guān)系對于所有關(guān)系R,要求它的每個屬性都是原子的。如果某個屬性是不可分的最小單元,則稱其是原子的。如果“出生年月”屬性定義為長度為6的字符串,那么其就是原子的;相反,如果“出生年月”定義為“年”+“月”,那么其就不是原子的。關(guān)系模型允許幾個屬性屬于相同的域。注意:空值NULL是一個特殊的值,表示值未知或不存在,其存在于所有的域??罩禃o數(shù)據(jù)庫訪問和更新帶來很多困難,所以要盡量避免使用空值。3.1.2數(shù)據(jù)庫模式數(shù)據(jù)庫模式(DataBaseSchema)是數(shù)據(jù)庫的邏輯設(shè)計,是由數(shù)據(jù)庫所包含的所有數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)、其間關(guān)系和約束條件組成的框架。數(shù)據(jù)庫實例(DataBaseInstance)是給定時刻數(shù)據(jù)庫中數(shù)據(jù)的一個快照,即在給定時刻在某種數(shù)據(jù)庫模式下的全體數(shù)據(jù)的集合。因而數(shù)據(jù)庫設(shè)計就是數(shù)據(jù)庫模式的設(shè)計。關(guān)系數(shù)據(jù)庫模式是基于關(guān)系模式的。關(guān)系模式(RelationSchema)是型,關(guān)系是值,關(guān)系模式是對關(guān)系的描述,它包括屬性序列、屬性來自的域、屬性與域之間的映像關(guān)系、元組語義描述以及完整性約束條件、屬性間的數(shù)據(jù)依賴關(guān)系的集合。關(guān)系模式可以形式化地表示為

R(U,D,DOM,F(xiàn))其中R是關(guān)系名,U是組成該關(guān)系的屬性的集合,D是屬性組U中屬性取值的域,DOM是屬性到域的映像規(guī)則的集合,F(xiàn)是屬性間的數(shù)據(jù)依賴關(guān)系的集合。關(guān)系模式定義的四元組中,D、DOM、F三個部分在關(guān)系運算理論研究中非常重要,其作用將在后續(xù)各章體現(xiàn),但在本章的論述中用處不多,所以本章將關(guān)系模式簡記為R(U)或R(A1,A2,…,An),其中R是關(guān)系名,A1,A2,…,A是屬性名,這里有U?=?(A1,A2,…,A)。這里n稱為關(guān)系的元數(shù),具有n個屬性的關(guān)系稱為n元關(guān)系。例如,表3.3給出的“銷售”關(guān)系的關(guān)系模式可以記為:銷售(工號,商品代碼,銷售數(shù)量),從中可以看出關(guān)系模式是對關(guān)系的描述,是靜態(tài)的、穩(wěn)定的。關(guān)系是關(guān)系模式在某一時刻的狀態(tài)或內(nèi)容值,是動態(tài)、隨時間不斷變化的。表3.3?“銷售”關(guān)系關(guān)系實例的概念對應(yīng)于程序設(shè)計語言中變量的值的概念,給定變量的值隨著時間的推移發(fā)生變化,當關(guān)系被更新時,關(guān)系實例的內(nèi)容也隨時間發(fā)生了變化。通常簡單地用“關(guān)系”指代“關(guān)系實例”。如表3.3的所有數(shù)據(jù)展示了關(guān)系模式“銷售(工號,商品代碼,銷售數(shù)量)”在某一時刻的一個關(guān)系實例。下面介紹幾個術(shù)語。

(1)候選碼:如果關(guān)系中的某一屬性組的值能唯一地標識一個元組,則稱該屬性組為侯選碼。候選碼的諸屬性稱為主屬性(PrimeAttribute),不包含在任何侯選碼中的屬性稱為非主屬性(Non-PrimeAttribute)。在簡單的情況下,候選碼只包含一個屬性。

(2)全碼(All-key):關(guān)系模式的所有屬性組都是這個關(guān)系模式的候選碼,稱為全碼(All-key)。若一個關(guān)系有多個候選碼,則選定其中一個為主碼。

(3)外碼、參照關(guān)系、被參照關(guān)系:設(shè)F是基本關(guān)系R的一個或一組屬性,但不是關(guān)系R的碼。如果F與基本關(guān)系S的主碼KS相對應(yīng),則稱F是基本關(guān)系R的外碼,基本關(guān)系R稱為參照關(guān)系(ReferencingRelation),基本關(guān)系S稱為被參照關(guān)系(ReferencedRelation)或目標關(guān)系(TargetRelation)。關(guān)系R和S不一定是不同的關(guān)系,目標關(guān)系S的主碼KS和參照關(guān)系的外碼F必須定義在同一個(或一組)域上,外碼并不一定要與相應(yīng)的主碼同名。當外碼與相應(yīng)的主碼屬于不同關(guān)系時,往往取相同的名字,以便于識別。

(4)模式圖:表示一個含有主碼和外碼依賴的數(shù)據(jù)庫模式的圖。例如一個“銷售”數(shù)據(jù)庫的E-R圖如圖3.1所示,圖3.2展示了該“銷售”數(shù)據(jù)庫的模式圖。圖中,每一個關(guān)系用矩形來表示,矩形內(nèi)列出屬性,矩形上面是關(guān)系的名字。如果有主碼屬性,用一條橫線將主碼屬性分隔在方框上部。外碼依賴用從參照關(guān)系的外碼屬性到被參照關(guān)系的主碼屬性之間的一個箭頭來表示。圖3.1“銷售”數(shù)據(jù)庫的E-R圖圖3.2“銷售”數(shù)據(jù)庫的模式圖3.1.3查詢語言查詢語言(QueryLanguage)是用戶向數(shù)據(jù)庫請求以獲取信息的語言。這些語言通常比一般的程序設(shè)計語言層次更高。查詢語言可以分為過程化的和非過程化的。在過程語言中,用戶指導(dǎo)系統(tǒng)對數(shù)據(jù)庫執(zhí)行一系列操作以計算所需的結(jié)果。在非過程語言中,用戶只需描述所需信息,而不用給出獲取該信息的具體過程。大多數(shù)商用關(guān)系數(shù)據(jù)庫系統(tǒng)提供的查詢語言中既包含過程化的部分,又包含非過程化的部分。常見的查詢語言有SQL、QBE、Datalog等。3.1.4關(guān)系數(shù)據(jù)模型的優(yōu)缺點關(guān)系型數(shù)據(jù)庫最大的特點在于它將每個具有相同屬性的數(shù)據(jù)獨立地存儲在一個表中。對任何一個表而言,用戶可以新增、刪除、修改表中任何一行的數(shù)據(jù),而不會影響表中其他的數(shù)據(jù)。它解決了層次型數(shù)據(jù)體橫向關(guān)聯(lián)不足的缺點,也避免了網(wǎng)狀數(shù)據(jù)庫關(guān)聯(lián)過于復(fù)雜的問題。關(guān)系數(shù)據(jù)模型具有下列優(yōu)點:

(1)關(guān)系模型與非關(guān)系模型不同,它是建立在嚴格數(shù)學(xué)概念的基礎(chǔ)上的。

(2)關(guān)系模型的概念單一。無論實體還是實體之間的關(guān)聯(lián)都用關(guān)系表示。數(shù)據(jù)的檢索結(jié)果也是關(guān)系(即表),因此,其數(shù)據(jù)結(jié)構(gòu)簡單、清晰,用戶易懂易用。

(3)關(guān)系模型的存取路徑對用戶透明,從而具有更高的數(shù)據(jù)獨立性和更好的安全保密性,也簡化了程序員的工作和數(shù)據(jù)庫開發(fā)的工作。關(guān)系數(shù)據(jù)模型誕生以后發(fā)展迅速,深受用戶的喜愛。當然,關(guān)系數(shù)據(jù)模型也有缺點,其最主要的缺點是,由于存取路徑對用戶透明,查詢效率往往不如非關(guān)系數(shù)據(jù)模型。因此為了提高性能,必須對用戶的查詢請求進行優(yōu)化,這增加了開發(fā)數(shù)據(jù)庫管理系統(tǒng)的難度。3.2關(guān)系代數(shù)任何一種運算都是將一定的運算符作用于一定的運算對象上,得到預(yù)期的運算結(jié)果。所以運算對象、運算符、運算結(jié)果是運算的三大要素。關(guān)系代數(shù)的運算對象是關(guān)系,運算結(jié)果亦為關(guān)系。關(guān)系代數(shù)是以集合代數(shù)為基礎(chǔ)發(fā)展起來的,它是以關(guān)系為運算對象的一組高級運算的集合。它包括一個運算的集合,這些運算以一個或兩個關(guān)系為輸入,產(chǎn)生一個新的關(guān)系作為結(jié)果。關(guān)系代數(shù)為關(guān)系模型操作提供了一個形式化基礎(chǔ),因而關(guān)系代數(shù)被看做是在關(guān)系數(shù)據(jù)庫管理系統(tǒng)(RDBMS)中實現(xiàn)和優(yōu)化查詢的基礎(chǔ)。RDBMS的SQL標準查詢語言中結(jié)合了關(guān)系代數(shù)中的一些概念。3.2.1基本運算在關(guān)系代數(shù)中,選擇、投影和更名運算都是對單一關(guān)系進行運算的關(guān)系操作,稱為一元運算。

1.選擇運算選擇(Selection)運算是根據(jù)某些條件對關(guān)系進行水平查詢,提取出符合條件的元組。查詢的條件用命題公式F表示;F是選擇謂詞表達式,其中的運算對象是常量(用引號括起來)或元組分量(屬性名或列的序號),其中的運算符有算術(shù)比較運算符(<,≤,>,≥,=,≠,這些符號統(tǒng)稱為θ符)和邏輯運算符(∧,∨,?);這里?{<,≤,>,≥}?適用于域是有序值的屬性,如數(shù)值域或日期域。如果屬性域是無序值的集合,那么只能使用集合?{=,≠}。用σ表示選擇,將條件表達式寫為σ的下標,那么關(guān)系R關(guān)于選擇謂詞F的選擇操作表示為σF(R),其形式化的定義如下:σF(R)?=?{t│t∈R∧F(t)?=?true}

例3.1“商品”關(guān)系如表3.4所示,若要在其中選擇生產(chǎn)商為“四川長虹電器有限公司”的元組。用選擇運算可以表示為σ生產(chǎn)商=“四川長虹電器有限公司”

(商品)表3.4“商品”關(guān)系本例選擇操作所產(chǎn)生的結(jié)果關(guān)系如表3.5所示。如果進一步“查找銷售價格大于1500元的所有元組”,則可以表示為σ銷售價格>1500(商品)。通常允許在選擇謂詞中進行比較,使用的是=,≠,<,≤,>和≥,還可以用連詞and(∧),or(∨)和not(?)將多個謂詞合并為一個較大的謂詞。如果查找“銷售價格大于1500,并由四川長虹電器公司生產(chǎn)的商品”,則可以表示為σ生產(chǎn)商=“四川長虹電器有限公司”∧銷售價格>1500(商品)表3.5σ生產(chǎn)商=“四川長虹電器有限公司”

(商品)的結(jié)果

2.投影運算投影(Projection)是對一個關(guān)系進行垂直分割,消去某列,并重新安排列的順序,再刪去重復(fù)元組。投影用π表示,將希望在操作結(jié)果中出現(xiàn)的屬性組作為π的下標,作為參數(shù)的關(guān)系放在π后的括號中。設(shè)有k元關(guān)系R(A1,A2,…,Ak),R在其分量(m≤k,i1,…,im為1到k之間的整數(shù))上的投影用表示,它是從R中選擇若干屬性列組成的一個m元關(guān)系。其形式化定義如下:

例3.2

列出“商品”關(guān)系中“所有商品代碼及銷售價格”可以表示為π商品代碼,銷售價格(商品)。投影操作所產(chǎn)生的結(jié)果關(guān)系如表3.6所示。表3.6商品代碼和銷售價格

3.并運算(Union)設(shè)關(guān)系R和關(guān)系S具有相同的元數(shù)n(即兩個關(guān)系都有n個屬性),且相應(yīng)的屬性取自同一個域,則關(guān)系R和關(guān)系S的并是由屬于R或?qū)儆赟的元組組成的關(guān)系。其結(jié)果仍為n元關(guān)系。記為R∪S。其形式化定義如下:R∪S?=?{t│t?∈R∨t∈S}其中,t是元組變量,R和S的元數(shù)相同。兩個關(guān)系的并運算是將兩個關(guān)系中的所有元組構(gòu)成一個新關(guān)系。并運算要求兩個關(guān)系屬性的性質(zhì)必須一致而且并運算的結(jié)果要消除重復(fù)的元組。要使并運算R∪S有意義,需要以下兩個條件同時成立:

(1)關(guān)系R和S必須是同元的,即它們的屬性數(shù)目必須相同;

(2)對所有的t,R的第t個屬性的域必須和S的第t個屬性的域相同。

例3.3

查詢銷售了T002和T006商品的營業(yè)員的工號。需要將銷售了T002和銷售了T006的員工集合并起來。具體可以表示為π工號(σ商品代碼=“T002”(銷售)∪σ商品代碼=“T006”(銷售))“銷售”關(guān)系,如前面的表3.3所示,則查詢所產(chǎn)生的結(jié)果關(guān)系如表3.7所示。表3.7例3.3查詢結(jié)果

4.差運算設(shè)關(guān)系R和關(guān)系S具有相同的元數(shù)n,且相應(yīng)的屬性取自同一個域,則關(guān)系R和關(guān)系S的差由屬于R而不屬于S的所有元組組成。其結(jié)果仍為n元關(guān)系。記為R?-?S。其形式化定義如下:R?-?S?=?{t?|?t∈R∧t

S}

例3.4

查詢所有未銷售商品的營業(yè)員的工號。該查詢可以用差運算來表示:π工號(營業(yè)員)?-?π工號(銷售)關(guān)系“營業(yè)員”和“銷售”參見表3.1和表3.3,則查詢所產(chǎn)生的結(jié)果關(guān)系如表3.8所示。表3.8未銷售商品的營業(yè)員

5.關(guān)系的笛卡兒積(CartesianProduct)設(shè)關(guān)系R和關(guān)系S的元數(shù)分別為r和s,定義關(guān)系R和關(guān)系S的笛卡兒積R?×?S是一個(r+s)元關(guān)系,所得關(guān)系的每個元組的前r個分量(屬性值)來自R的一個元組,后s個分量來自S的一個元組,記為R?×?S。其形式化定義如下:R?×?S?=?{trts?|?tr∈R∧ts∈S}若R有n個元組,S有m個元組,則R?×?S有n?×?m個元組,n?×?m稱為該笛卡兒積的基數(shù)。為了簡化描述笛卡爾積的概念,需要構(gòu)造“銷售”關(guān)系的子關(guān)系,取名“銷售子關(guān)系”,該構(gòu)造的關(guān)系代數(shù)操作為σ工號=“003”∧工號=“004”(銷售),所得操作結(jié)果如表3.9所示。表3.9銷售子關(guān)系

例3.5求解“商品”關(guān)系和“銷售”子關(guān)系的笛卡兒積。關(guān)系“銷售”和“商品”的笛卡兒積的關(guān)系模式可以表示為

(銷售.工號,銷售.商品代碼,銷售.銷售日期,銷售.銷售數(shù)量,商品.商品代碼,商品.商品名稱,商品.生產(chǎn)商,商品.銷售價格)用“.”分級的模式,可以區(qū)別“銷售.商品代碼”和“商品.商品代碼”。對只在兩個關(guān)系模式之一中出現(xiàn)的屬性,通常省略其關(guān)系名前綴,所以可以將上述的關(guān)系模式簡寫為

(工號,銷售.商品代碼,銷售日期,銷售數(shù)量,商品.商品代碼,商品名稱,生產(chǎn)商,銷售價格)參與笛卡兒積運算的關(guān)系的名字必須不同?!吧唐贰标P(guān)系和“銷售”子關(guān)系的笛卡兒積如表3.10所示。表3.10“商品”關(guān)系和“銷售”子關(guān)系的笛卡兒積3.2.2擴展運算關(guān)系代數(shù)的基本運算足以表達任何關(guān)系代數(shù)查詢。但是不能局限于基本運算,因為某些常用查詢表達出來會顯得冗長,所以需要定義一些擴展運算,可以簡化一些常用的查詢。

1.交運算用“∩”表示關(guān)系交運算。設(shè)關(guān)系R和關(guān)系S具有相同的元數(shù)n,且相應(yīng)的屬性取自同一個域。關(guān)系R和關(guān)系S的交記為R∩S,其結(jié)果仍為n元的關(guān)系,是由既屬于R又屬于S的元組成。其形式化定義如下:R∩S?=?{t│t∈R∧t∈S}其中,t是元組變量,R和S的元數(shù)相同。關(guān)系的交也可以用關(guān)系的差來表示,即:R∩S

=

R

(R

S)或R∩S

=

S

(S

R)

例3.6查詢既銷售了T002商品又銷售了T003商品的營業(yè)員的工號。在“銷售”關(guān)系中分別求出銷售了T002和T003商品的銷售子關(guān)系,然后用交運算求解。π工號(σ商品代碼=“T002”(銷售)∩σ商品代碼=“T003”(銷售))運算產(chǎn)生的結(jié)果關(guān)系如表3.11所示。表3.11例3.6操作結(jié)果

2.自然連接運算對有些要用到笛卡兒積的查詢進行簡化常常是必要的。自然連接運算(Naturaljoin),可以將某些選擇和笛卡兒積運算合并為一個運算。“連接”用符號“??”來表示。自然連接是一種特殊的等值連接,它要求兩個關(guān)系中進行比較的分量必須是相同的屬性組,并且要在結(jié)果中把重復(fù)的屬性去掉。自然連接運算首先形成它的兩個關(guān)系的笛卡兒積,然后基于兩個關(guān)系模式中都出現(xiàn)的屬性上的相等性進行選擇,最后還要去除重復(fù)屬性。盡管自然連接的定義很復(fù)雜,使用起來卻很方便。自然連接具體計算過程如下:

(1)計算R?×?S。

(2)設(shè)R和S的公共屬性是A1,…,Ak,挑選R?×?S中滿足R.A1?=?S.A1,…,R.Ak

=?S.Ak的那些元組。

(3)去掉S.A1,…,S.Ak這些列(保留R.A1,…,R.Ak列)。自然連接的形式化定義如下:

R???S?=?πR∪S其中R∪S表示由關(guān)系R和S的屬性構(gòu)成的集合。例3.7

查詢所有銷售人員的工號及銷售的商品代碼和銷售價格??梢杂米匀贿B接表示該查詢:π工號,商品代碼,銷售價格(銷售???商品)“銷售”、“商品”關(guān)系,如前面的表3.3和表3.4所示。則查詢所產(chǎn)生的結(jié)果關(guān)系如表3.12所示。表3.12π工號,商品代碼,銷售價格(銷售??商品)

3.除(Division)運算

R、?S是兩個關(guān)系且S?R,R與S的除法是寫為R?÷?S的二元關(guān)系,其結(jié)果是模式R?-?S(結(jié)果關(guān)系的屬性僅僅取自于關(guān)系R的屬性)上的關(guān)系,并且結(jié)果關(guān)系中的元組與S中的元組的所有組合構(gòu)成的元組都存在于R中。除法的形式定義如下:

R÷S={t?[a1,…,an]?|?t∈R∧?s∈S((t[a1…,an]∪s)∈R)}其中a1,…,an是R的屬性名字的集合并且不屬于S的屬性集合,通常要求在S的屬性集合是R的屬性集合的子集,否則運算的結(jié)果永遠為空。

例3.8求表3.13所示“關(guān)系R”和表3.14所示“關(guān)系S”的除法。

R÷S除法產(chǎn)生的關(guān)系如表3.15所示。如果關(guān)系S包含了康佳集團的的所有產(chǎn)品,則這個除法的結(jié)果精確地包含了銷售過康佳集團所有產(chǎn)品的銷售人員。表3.13關(guān)系R

表3.14關(guān)系S表3.15關(guān)系R÷S3.3擴展的關(guān)系代數(shù)在關(guān)系代數(shù)運算的發(fā)展過程中,基本的關(guān)系代數(shù)具有一定的局限性,為了進一步方便用戶,增強檢索功能,需要引進擴展的關(guān)系代數(shù)。這里主要包括廣義投影、聚集運算、外連接等運算。

3.3.1廣義投影廣義投影運算通過允許在投影列表中使用代數(shù)函數(shù)來對投影進行擴展。投影操作是對一個關(guān)系進行垂直分割,消去某些列,并重新安排列的順序,再刪去重復(fù)元組。其運算形式定義如下:其中,E是任意關(guān)系代數(shù)表達式,而F1,F(xiàn)2,…,F(xiàn)n中的每一個都是涉及常量以及E的模式中屬性的算數(shù)表達式。特別地,算術(shù)表達式可以僅僅是個屬性或常量。在制作列中需要產(chǎn)生計算值的報表時,這個操作可以作為一個幫助性的操作。

例3.9根據(jù)表3.1“營業(yè)員”關(guān)系中的出生年份,通過當前所在年份,計算出營業(yè)員的年齡。其廣義投影運算可以表示為π工號,姓名,出生年份,(2009-出生年份)(營業(yè)員)表達式“2009-出生年份”產(chǎn)生的屬性沒有名字,可以通過對廣義投影的結(jié)果重命名的方式給它一個名字。屬性更名可以與廣義投影相結(jié)合,具體表示為π工號,姓名,出生年份,(2009-出生年份)as年齡

(營業(yè)員)這個廣義投影的第四個屬性被命名為年齡。對表3.1應(yīng)用上述運算,得到的結(jié)果如表3.16所示。表3.16

工號,姓名,出生年份,(2009-出生年份)as年齡

(營業(yè)員)3.3.2聚集運算在數(shù)據(jù)庫處理中,經(jīng)常需要計算總數(shù)、平均值、最大值等聚集操作,所以查詢系統(tǒng)提供了對數(shù)據(jù)的聚集運算。

1.聚集函數(shù)(AggregateFunction)聚集函數(shù)通常對一個輸入集合進行計算,然后將單一值作為結(jié)果返回。有時,在計算聚集函數(shù)前,還必須去除重復(fù)值。去除重復(fù)值,仍然使用所需的聚集函數(shù)名,但用連字符將“Distinct”附加在函數(shù)名后。常用的聚集函數(shù)如表3.17所示。表3.17常用的聚集函數(shù)

2.聚集運算(AggregateOperation)聚集運算g的形式定義如下:其中E是任意關(guān)系代數(shù)表達式,G1,G2,…,Gn是用于聚集分組的一系列屬性;每個Fi是一個聚集函數(shù),每個Ai是一個屬性名。該運算的含義是:表達式E中的元組被分成若干組,使得同一組中所有元組在G1,G2,…,Gn上的值相同,而不同組中元組在G1,G2,…,Gn上的值不同。例3.10參照表3.3“銷售”關(guān)系,按照“工號”對商品代碼元組分組,這樣每個分組將包含同一個營業(yè)員賣出的不同商品代碼的商品。接著可以計算出每一個工號所對應(yīng)的銷售數(shù)量的平均值。該運算可以表示為工號gavg(銷售數(shù)量)(銷售)聚集分組中間結(jié)果如表3.18所示。但這不是聚集計算的最終結(jié)果,最終結(jié)果需要去掉無用的列和重復(fù)的元組。該運算的最終結(jié)果如表3.19所示。表3.18聚集分組中間結(jié)果表3.19聚集運算結(jié)果3.3.3外連接連接又叫內(nèi)連接(InnerJoin),它可以保證兩個表中所有的行都滿足連接條件,這使它具有局限性。在一些應(yīng)用中,需要使用外連接(OuterJoin)。在外連接中,某些不滿足條件的列也會顯示出來,也就是說,只限制一個表中的行,而不限制另外一個表中的行。這種連接形式在許多情況下是非常有用的。外連接運算是連接運算的擴展,可以處理缺失的信息。使用外連接運算可以避免信息丟失。外連接只能用于兩個表,它改變了兩張表的數(shù)據(jù)匹配方式。外連接特別描述了當一張表中的值在另一張表中不出現(xiàn)時該如何處理的問題。

1.外連接的分類外連接可以是左外連接(LeftJoin或LeftOuterJoin)、右外連接(RightJoin或RightOuterJoin)或全外連接(FullOuterJoin或FullJoin)。這3種形式的外連接都需要計算連接,然后在連接結(jié)果上附加額外的元組。

1)左外連接左外連接的結(jié)果集中包含LEFTOUTER子句中指定的左表的所有行,而不僅僅是連接屬性所匹配后得到的行。如果左表的某行在右表中沒有相應(yīng)的匹配行,則在左外連接的結(jié)果集中添加一個特殊元組,該元組左半部分由左表的未匹配的元組構(gòu)成,而其右半部分由對應(yīng)右表的一個空行構(gòu)成。

2)右外連接右外連接和左外連接相反,其結(jié)果將返回右表的所有行,如果右表的某行在左表中沒有匹配行,則將其與左表一個空行組合成一個結(jié)果元組。

3)全外連接全外連接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則將其與一個空行匹配構(gòu)成一個結(jié)果元組。

4)內(nèi)連接與外連接的區(qū)別內(nèi)連接消除了與另一個表中的任何行不匹配的行。注意:使用外連接必須小心,特別是全外連接。兩張沒有公共數(shù)據(jù)的規(guī)模比較大的表的連接結(jié)果十分巨大且沒有意義。

2.外連接實例

例3.11

查詢所有銷售人員的個人信息及其銷售信息。如果內(nèi)連接可以表示為:營業(yè)員??銷售,這時查詢結(jié)果如表3.20所示。從表3.20可知,營業(yè)員李冰、趙欣、趙潔和王小川已經(jīng)丟失,可見內(nèi)連接已經(jīng)不能滿足查詢需求??梢杂米笸膺B接實現(xiàn)這個查詢,查詢結(jié)果如表3.21所示。表3.20內(nèi)連接的查詢結(jié)果表3.21營業(yè)員和銷售的左外連接的結(jié)果3.4數(shù)據(jù)庫的修改操作本節(jié)討論數(shù)據(jù)庫添加、刪除和修改等運算操作。3.4.1數(shù)據(jù)刪除刪除操作形式定義如下:R?←?R?–?E,其中R是關(guān)系而E是關(guān)系代數(shù)查詢。下面列舉幾個關(guān)系代數(shù)中刪除請求的例子。

例3.12在“營業(yè)員”關(guān)系中刪除李冰的所有記錄。營業(yè)員?←?營業(yè)員?-?σ姓名=“李冰”(營業(yè)員)

例3.13刪除銷售價格在0~1000之間的所有商品。商品?←?商品?~?σ銷售價格>=0∧銷售價格<=1000(商品)

例3.14刪除營業(yè)員張杰所銷售的所有商品。R?←σ姓名=“張杰”(營業(yè)員?????銷售)S?←π商品代碼(R)商品?←?商品?-?σ銷售代碼∈S(商品)3.4.2數(shù)據(jù)插入向關(guān)系中插入數(shù)據(jù),可以插入一個元組,也可以插入一個查詢結(jié)果的集合。插入操作在關(guān)系代數(shù)中的形式定義如下:R←R∪E其中R是關(guān)系,E是關(guān)系代數(shù)表達式。如果E是只包含一個元組的常量,就表示向關(guān)系中插入單個元組。

例3.15向銷售關(guān)系中插入營業(yè)員金文銷售了10臺T002的信息。該插入操作可以表示為V?←π工號(σ姓名=“金文”(營業(yè)員))營業(yè)員?←?營業(yè)員∪{(V,T002,10)}

例3.16查詢所有已經(jīng)銷售的商品的基本信息、銷售數(shù)量以及相應(yīng)銷售人員的信息,并把查詢結(jié)果形成新的查詢關(guān)系。該查詢可以表示為R?←?(商品???銷售???營業(yè)員)3.4.3數(shù)據(jù)更新在某些情況下,可以用廣義投影運算來改變元組中的某個值,其形式定義如下:

R?←其中,當?shù)趇個屬性不被修改時,F(xiàn)i是R的第i個屬性;當?shù)趇個屬性將被修改時,F(xiàn)i是一個只涉及常量和R的屬性表達式,該表達式給出了此屬性的新值。如果希望選出一些元組并只對這些元組進行修改,可以用下述表達式:

R?←

(σP(R))∪(R?-σP(R))P代表用于選擇需要修改的元組的條件。

例3.17將所有商品價格增加10%,可以表示為商品?←π商品代碼,商品名稱,生產(chǎn)商,銷售價格*1.1(商品)

例3.18將銷售價格超過1500的價格增加5%,其余價格均增加10%。該操作可以表示為商品?←π商品代碼,商品名稱,生產(chǎn)商,銷售價格*1.05(σ銷售價格?>1500(商品))∪π商品代碼,商品名稱,生產(chǎn)商,銷售價格*1.1(σ銷售價格?<=1500(商品))3.5SQL

SQL是英文StructuredQueryLanguage的縮寫,譯為結(jié)構(gòu)化查詢語言,是一種介于關(guān)系代數(shù)與關(guān)系運算之間的語言,目前已成為關(guān)系數(shù)據(jù)庫的標準語言。SQL語言之所以能夠為用戶和業(yè)界所接受,成為國際標準,是因為它是一個綜合、通用、功能極強同時又簡潔易學(xué)的語言。SQL語言集數(shù)據(jù)查詢(DataQuery)、數(shù)據(jù)操縱(DataManipulation)、數(shù)據(jù)定義(DataDefinition)和數(shù)據(jù)控制(DataControl)功能于一體,充分體現(xiàn)了關(guān)系數(shù)據(jù)語言的特點和優(yōu)點。下面介紹SQL語言的主要特點。

1.一體化

SQL語言集數(shù)據(jù)定義語言DDL、數(shù)據(jù)操縱語言DML、數(shù)據(jù)控制語言DCL的功能于一體,所以其語言風格統(tǒng)一,可以獨立完成數(shù)據(jù)庫生命周期中的全部活動,包括定義關(guān)系模式、錄入數(shù)據(jù)、建立數(shù)據(jù)庫、查詢、更新、維護、數(shù)據(jù)庫重構(gòu)、數(shù)據(jù)庫安全性控制等一系列操作要求,這就為數(shù)據(jù)庫應(yīng)用系統(tǒng)開發(fā)者提供了友好的環(huán)境。例如用戶在數(shù)據(jù)庫投入運行后,可根據(jù)需要隨時逐步修改模式,而不影響數(shù)據(jù)庫的運行,因此使系統(tǒng)具有良好的可擴充性。

2.高度非過程化非關(guān)系數(shù)據(jù)模型的數(shù)據(jù)操縱語言是面向過程的語言,用其完成某項請求,必須指定存取路徑。而用SQL語言進行數(shù)據(jù)操作,用戶只需提出“做什么”,而不必指明“怎么做”,因此用戶無需了解存取路徑,存取路徑的選擇以及SQL語句的操作過程由系統(tǒng)自動完成。這不但大大減輕了用戶負擔,而且有利于提高數(shù)據(jù)獨立性。

3.簡潔

SQL語言功能極強,設(shè)計巧妙,語言十分簡潔,完成數(shù)據(jù)定義、數(shù)據(jù)操縱、數(shù)據(jù)控制的核心功能只用了9個動詞:CREATE、DROP、SELECT、INSERT、UPDATE、DELETE、GRANT、REVOKE;而且SQL語言語法簡單,接近英語口語,因此容易學(xué)習(xí)、容易使用。

4.能以多種方式使用

SQL語言既是自含式語言,又是嵌入式語言。作為自含式語言,它能夠獨立地用于聯(lián)機交互的使用方式,用戶可以在終終端鍵盤上直接鍵入SQL命令對數(shù)據(jù)庫進行操作。作為嵌入式語言,SQL語句能夠嵌入到高級語言(例如C、C++、JAVA)程序中,供程序員設(shè)計程序時使用。在兩種不同的使用方式下,SQL語言的語法結(jié)構(gòu)基本上是一致的。這種以統(tǒng)一的語法結(jié)構(gòu)提供兩種不同的使用方式的做法,為用戶提供了極大的靈活性與方便性。

5.面向集合的操作方式

SQL語言采用集合操作方式,不僅查找結(jié)果可以是元組的集合,而且一次插入、刪除、更新操作的對象也是元組的集合。3.5.1SQL基本結(jié)構(gòu)

SQL的功能分成4部分:數(shù)據(jù)定義、數(shù)據(jù)查詢、數(shù)據(jù)操縱、數(shù)據(jù)控制。SQL語言的動詞如表3.22所示。本節(jié)將使用連鎖超市數(shù)據(jù)庫中的3個關(guān)系來學(xué)習(xí)SQL的用法。表3.23~3.25分別代表營業(yè)員、銷售和商品3個關(guān)系。為了描述SQL需要,這里定義的3個關(guān)系與表3.1、表3.4、表3.5所示的有所不同。表3.22SQL語言的主要動詞表3.23“營業(yè)員”表

表3.24“銷售”表表3.25“商品”表

1.數(shù)據(jù)庫的創(chuàng)建和刪除

(1)創(chuàng)建數(shù)據(jù)庫的語法格式如下:CREATEDATABASE<數(shù)據(jù)庫名>;其中,CREATEDATABASE是關(guān)鍵字,本書后面的關(guān)鍵字均用大寫字母書寫。SQL以“;”作為語句分割符,表示一個SQL語句結(jié)束。例3.19

建立“超市”數(shù)據(jù)庫。代碼如下:CREATEDATABASE超市;

(2)刪除數(shù)據(jù)庫的語法格式如下:DROPDATABASE<數(shù)據(jù)庫名><CASCADE|RESTRICT>其中,若使用CASCADE(級聯(lián)),則在刪除數(shù)據(jù)庫的同時把該數(shù)據(jù)庫中所有的數(shù)據(jù)庫對象全部刪除;若使用RESTRICT(限制),則該數(shù)據(jù)庫中如果定義了下屬的數(shù)據(jù)庫對象(如表、視圖等),會拒絕該刪除語句的執(zhí)行。只有當該數(shù)據(jù)庫中沒有任何下屬的對象時才能執(zhí)行刪除操作。

例3.20刪除“超市”數(shù)據(jù)庫,同時刪除該數(shù)據(jù)庫中所定義的表。該操作的代碼如下:DROPDATABASE超市CASCADE;

2.基本表的定義在SQL中關(guān)系稱為“表”、元組稱為“行”、屬性稱為“列”。有時“表”也稱為基本表。

1)創(chuàng)建基本表創(chuàng)建表的語法格式如下:

CREATETABLE<表名>

(<列名><數(shù)據(jù)類型>[<列級完整性約束條件>]

[,<列名><數(shù)據(jù)類型>[<列級完整性約束條件>]]…

[,<表級完整性約束條件>]);其中,如果完整性約束條件涉及到該表的多個屬性列,則必須定義在表級上,否則既可以定義在列級上也可以定義在表級上。

例3.21在“超市”數(shù)據(jù)庫中創(chuàng)建“營業(yè)員”、“商品”和“銷售”3個表。該創(chuàng)建操作的代碼如下:

CREATETABLE營業(yè)員

(工號CHAR(6)PRIMARYKEY,姓名CHAR(6),工作年月CHAR(8),出生年月CHAR(8),聯(lián)系電話CHAR(8));

CREATETABLE商品

(商品代碼CHAR(6)PRIMARYKEY,商品名稱CHAR(20),生產(chǎn)商CHAR(20),銷售價格FLOAT(2),生產(chǎn)日期DATETIME);

CREATETABLE銷售

(工號CHAR(6),商品代碼CHAR(6),銷售日期DATETIME,銷售數(shù)量INT,

PRIMARYKEY(工號,商品代碼),

FOREIGNKEY(工號)REFERENCES營業(yè)員(工號),

FOREIGNKEY(商品代碼)REFERENCES商品(商品代碼));其中,基本表的每個列是一個原子的數(shù)據(jù)變量,具有一定的數(shù)據(jù)類型和約束條件描述。在創(chuàng)建營業(yè)員表的SQL語句中,“工號CHAR(6)PRIMARYKEY”表示“工號”列是一個長度為6個字符的字符串;PRIMARYKEY是一個約束條件,表示該列是“營業(yè)員”表的主碼。在創(chuàng)建銷售表的SQL語句中,“FOREIGNKEY(工號)REFERENCES營業(yè)員(工號)”定義了表級的約束條件,表示“工號”列是該表的外碼,對應(yīng)于“營業(yè)員”表的工號列。

SQL中域的概念用數(shù)據(jù)類型來實現(xiàn),定義表的屬性時,需要指明其數(shù)據(jù)類型及長度。表3.26列出了SQL的主要數(shù)據(jù)類型。表3.26SQL主要數(shù)據(jù)類型表

2)修改基本表結(jié)構(gòu)修改基本表的語法格式如下:

ALTERTABLE<表名>

[ADD<新列名><數(shù)據(jù)類型>[完整性約束]]

[DROP<完整性約束名>]

[ALTERCOLUMN<列名><數(shù)據(jù)類型>];其中,<表名>是要修改的基本表,ADD子句用來向基本表增加一個新列或新的完整性約束條件,DROP子句用于刪除指定的完整性約束條件,ALTERCOLUMN子句用于修改原有列的定義,包括修改列名和數(shù)據(jù)類型。

例3.22向“營業(yè)員”表增加“家庭地址”列。

ALTERTABLE營業(yè)員ADD家庭地址CHAR(10);例3.23

將“營業(yè)員”表的聯(lián)系電話列的數(shù)據(jù)類型改為整型。

ALTERTABLE營業(yè)員ALTER聯(lián)系電話INT;例3.24

向“商品”表增加“商品名稱必須取唯一值”的約束條件。

ALTERTABLE商品ADDUNIQUE(商品名稱);

3)刪除基本表刪除基本表的語法格式如下:

DROPTABLE<表名><CASCADE|RESTRICT>其中,若使用CASCADE(級聯(lián)),則在刪除表的同時把相關(guān)的依賴對象全部刪除;若使用RESTRICT(限制),則如果該表被其他表的約束所引用,或者該表上建立了視圖、觸發(fā)器、存儲過程等,會拒絕該刪除語句的執(zhí)行;缺省時是RESTRICT。

例3.25刪除營業(yè)員基本情況表。

DROPTABLE營業(yè)員CASCADE;

3.索引的建立與刪除建立索引是加快查詢速度的有效手段。用戶可以根據(jù)需要,在基本表上建立一個或多個索引。建立合理的索引,可以加速數(shù)據(jù)的檢索過程。

SQLServer采用B-?樹結(jié)構(gòu)的索引,根據(jù)索引的順序與數(shù)據(jù)表的物理順序是否相同可以分為:聚集索引(ClusteredIndex)和非聚集索引(NonclusteredIndex)。

(1)聚集索引重新組織表中的數(shù)據(jù)以按指定的一個或多個列的值排序。聚集索引的葉節(jié)點包含實際的數(shù)據(jù),因此用它查找數(shù)據(jù)很快,但每個表只能建立一個聚集索引。建立聚集索引后,更新該列上的數(shù)據(jù)時,往往會導(dǎo)致表中記錄的物理順序的變更,代價較大,所以對于經(jīng)常更新的列不宜建立聚集索引。

(2)非聚集索引不重新組織表中的數(shù)據(jù),它的葉節(jié)點存儲了組成非聚集索引的列值和行的定位指針。一個表可以建立249個非聚集索引。

1)聚集索引的使用在聚集索引下,數(shù)據(jù)在物理上按順序排在數(shù)據(jù)頁上,重復(fù)值也排在一起,因而在那些包含范圍檢查(BETWEEN、<、<=、>、>=)或使用GROUPBY、ORDERBY的查詢時,一旦找到具有范圍中第一個鍵值的行,具有后續(xù)索引值的行一定連在一起,不必進一步搜索,避免了大范圍掃描,可以大大提高查詢速度。

2)非聚集索引的使用由于非聚集索引的葉節(jié)點不包含實際的數(shù)據(jù),因此它檢索效率較低,但是一個表只可以建立一個聚集索引,當用戶需要建立多個索引時就需要使用非聚集索引了。在建立非聚集索引時,要權(quán)衡索引加快查詢速度與降低修改速度之間的利弊??傊?,在良好的數(shù)據(jù)庫設(shè)計基礎(chǔ)上,有效地使用索引是數(shù)據(jù)庫應(yīng)用系統(tǒng)取得高性能的基礎(chǔ)。然而,任何事物都具有兩面性,索引也不例外。索引的建立需要占用額外的存儲空間,并且在增、刪、改的操作中也會增加一定的工作量,在適當?shù)牡胤皆黾舆m當?shù)乃饕瑥牟缓侠淼牡胤絼h除次要的索引,將有助于優(yōu)化那些性能較差的數(shù)據(jù)庫應(yīng)用系統(tǒng)。

3)建立索引建立索引語法格式如下:

CREATE[UNIQUE][CLUSTER]INDEX<索引名>

ON<表名>(<列名>[<次序>][,<列名>[<次序>]]…);其中,<表名>是要建立索引的基本表的名字。索引可以建立在該表的一列或多個列上,各列間用逗號分隔。每個<列名>后面還可以用<次序>指定索引值的排列次序,可以選ASC(升序)或DESC(降序),缺省值為ASC。UNIQUE表明此索引的每一個索引值只能對應(yīng)唯一的數(shù)據(jù)記錄。CLUSTERED表示要建立的索引是聚集索引。例3.26在營業(yè)員表的姓名列上建立一個聚集索引。

CREATECLUSTEREDINDEX營業(yè)員-姓名ON營業(yè)員(姓名);

例3.27營業(yè)員表按工號升序建立唯一索引。

CREATEINDEX營業(yè)員-工號ON營業(yè)員(工號);

例3.28商品表按商品代碼升序建立唯一索引。

CREATEINDEX商品-商品代碼ON商品(商品代碼);

例3.29銷售表按工號升序和商品代碼降序建立唯一索引。

CREATEINDEX工號-商品代碼ON銷售(工號ASC,商品代碼DESC);

4)刪除索引刪除索引語法格式如下:

DROPINDEX<索引名>;刪除索引時,系統(tǒng)會從數(shù)據(jù)字典中刪去有關(guān)該索引的描述。

例3.30刪除例3.28所建立的“營業(yè)員-工號”索引。

DROPINDEX營業(yè)員-工號;

4.數(shù)據(jù)的查詢查詢語句的語法格式如下:

SELECT[ALL|DISTINCT]<目標列表達式>[,<目標列表達式>]…

FROM<表名或視圖名>[,<表名或視圖名>]…

[WHERE<條件表達式>]

[GROUPBY<分組依據(jù)列>]

[HAVING<條件表達式>]

[ORDERBY<排序依據(jù)列>[ASC|DESC]];其中,根據(jù)WHERE子句的條件表達式,從FROM子句制定的基本表或視圖中找出滿足條件的元組,再按照SELECT子句中的目標列表達式,選出元組中的屬性值形成結(jié)果表。如果有GROUPBY子句,則將結(jié)果按分組的列值進行分組,該屬性列值相等的元組為一個組,通常在每組中會應(yīng)用聚集函數(shù)。如果GROUPBY子句中包含HAVING短語,則只有滿足制定條件的組才給予輸出。如果有ORDERBY子句,則將結(jié)果表按照排序依據(jù)列的值進行升序或降序排列。

SELECT語句可以進行單表查詢、復(fù)雜的連接查詢、嵌套查詢。單表查詢僅僅涉及一個表。下面以連鎖超市數(shù)據(jù)庫中的3張表為例學(xué)習(xí)單表查詢。

1)簡單查詢在數(shù)據(jù)庫中,一般情況下,每個表都包含若干個列信息。用戶在查詢表中的記錄時,大多數(shù)情況下只是關(guān)心表的一列或者幾列的信息。這時,只需要使用SELECT語句的常規(guī)使用方式即可。語法格式如下:

SELECT列名1[,列名2,…列名n]

FROM表名;其中,SELECT關(guān)鍵詞指明要查詢的表的列名,F(xiàn)ROM關(guān)鍵詞指明要查詢的列所在的表名。

例3.31[查詢單列數(shù)據(jù)]查詢?nèi)w營業(yè)員的姓名。本例代碼如下:

SELECT姓名

FROM營業(yè)員;運行該代碼,得到的查詢結(jié)果如圖3.3所示。在SQL語言中,SQL關(guān)鍵詞對大小寫不敏感,所以對SELECT關(guān)鍵詞來說,SELECT、select或者Select都是一樣的。在SQLSERVER中,其字段名稱對大小寫也不敏感。圖3.3查詢姓名列的數(shù)據(jù)例3.32[查詢多列數(shù)據(jù)]查詢?nèi)w營業(yè)員的工號、姓名及其工作年月。本例代碼如下:

SELECT工號,姓名,工作年月

FROM營業(yè)員運行該代碼,得到的查詢結(jié)果如圖3.4所示。多列查詢需要在SELECT關(guān)鍵詞后指定要查詢的列,但是各列之間必須用逗號分開。圖3.4查詢多列數(shù)據(jù)的結(jié)果例3.33[去除查詢結(jié)果的重復(fù)信息—DISTINCT]查詢銷售表中所有銷售員的工號,即查詢工號列的數(shù)據(jù),且去除重復(fù)的記錄。前面介紹的最基本的查詢方式會返回從表格中搜索到的所有行的數(shù)據(jù),而不管這些數(shù)據(jù)是否重復(fù),這常常不是用戶希望看到的。使用DISTINCT關(guān)鍵字就能夠從返回的結(jié)果數(shù)據(jù)集合中刪除重復(fù)的行,使返回的結(jié)果更簡潔。在SELECT子句中,通過指明DISTINCT關(guān)鍵字去除列中的重復(fù)信息。語法如下:

SELECTDISTINCT列名FROM表名;其中,DISTINCT關(guān)鍵字去除的是SELECT子句查詢的列的重復(fù)信息。如果SELECT子句查詢的列為多列,那么只有這些列的信息同時重復(fù)的記錄才被去除。本例代碼如下:

SELECTDISTINCT工號

FROM銷售;運行該代碼,得到的查詢結(jié)果如圖3.5所示。以上結(jié)果集中的重復(fù)記錄被刪除了,同時對結(jié)果集中的數(shù)據(jù)按照升序進行了排序。實際上,DBMS的操作過程是先對查詢結(jié)果排序,而后查找并去除結(jié)果集中重復(fù)的值。使用DISTINCT是要付出代價的。因為要去掉重復(fù)值,必須對結(jié)果集中的記錄進行排序,使得相同的記錄聚集在一起,只有按這種方法對記錄進行分組,才能去掉重復(fù)值,而這一工作甚至比查詢本身還費時間。在使用DISTINCT關(guān)鍵字后,如果表中有多個為NULL的數(shù)據(jù),服務(wù)器會把這些數(shù)據(jù)視為相等。圖3.5去除重復(fù)信息的工號列的數(shù)據(jù)例3.34[用“*”查詢所有列]?查詢?nèi)w營業(yè)員的所有列信息。除了能夠進行單列查詢和多列查詢以外,使用SELECT語句還可以查詢表中的所有列,這是通過星號(?*?)通配符實現(xiàn)的。語法如下:

SELECT*FROM表名;使用“*”通配符,查詢結(jié)果將顯示表中所有列的元素,因此無需指明各列的列名,這在用戶不清楚表中各列的列名時非常有用。服務(wù)器會按用戶創(chuàng)建表時所聲明的列的順序來顯示所有的列。本例代碼如下:

SELECT*

FROM營業(yè)員;運行該代碼,得到的查詢結(jié)果如圖3.6所示。圖3.6營業(yè)員表中所有列的記錄

注意:使用“?*?”通配符時要慎重,在不需要查詢所有列時,盡量采用前面介紹的單列查詢或多列查詢,以免占用過多的資源。

2)帶有搜索條件的查詢一個數(shù)據(jù)表中存放著大量相關(guān)的記錄數(shù)據(jù)。實際使用時,往往只需要其中滿足要求的部分記錄,這時就需要用到WHERE條件子句。WHERE子句允許指定查詢條件,使得SELECT語句的結(jié)果表中只包含那些滿足查詢條件的記錄。語法格式如下:

SELECT列名1[,列名2,…列名n]FROM表名WHERE條件;其中,WHERE子句必須緊跟在FROM子句后面。SQLSERVER對WHERE子句中的查詢條件的數(shù)目沒有限制。WHERE子句中的條件表達式包括算術(shù)表達式和邏輯表達式兩種,表達式中通常包含一些操作符。表3.27給出了WHERE子句中允許使用的操作符?!癖容^操作符的用法在對字符串類型的字段使用比較操作符時,是根據(jù)字符的排列順序進行比較的。字符串的排序是根據(jù)其首字母的順序進行的,如果首字符相同,則比較下一個字符,依此類推。對于漢字的排序,是根據(jù)其漢語拼音的第一個字母的順序進行的,如果第一個字母相同,則比較第二個字母,依此類推,且漢字的順序要高于字母的順序。表3.27操作符列表例3.35

查詢“銷售”表中“商品代碼”為T002的記錄。本例代碼如下:

SELECT*

FROM銷售

WHERE商品代碼='T002';運行該代碼,得到的查詢結(jié)果如圖3.7所示。圖3.7銷售表中“商品代碼”為T002的記錄例3.36

查詢“營業(yè)員”表中“出生年月”大于1972年的營業(yè)員的姓名和出生年月。本例代碼如下:

SELECT姓名,出生年月

FROM營業(yè)員

WHEREleft(出生年月,4)>'1972';運行該代碼,得到的查詢結(jié)果如圖3.8所示。圖3.8出生年月大于1972年的記錄例3.37

在“營業(yè)員”表中查年齡不大于38歲的營業(yè)員的姓名、工號、出生年月。本例代碼如下:

SELECT姓名,工號,出生年月

FROM營業(yè)員

WHERE2009-LEFT(出生年月,4)!?>?38;運行該代碼,得到的查詢結(jié)果如圖3.9所示?!袷褂没镜倪壿嫳磉_式——NOT、AND、OR在WHERE子句中,可以使用多個搜索條件選擇記錄(行),即通過邏輯運算符(NOT、AND或OR)將多個單獨的搜索條件結(jié)合在一個WHERE子句中,形成一個復(fù)合的搜索條件。當對復(fù)合搜索條件求值時,DBMS對每個單獨的搜索條件求值,然后執(zhí)行布爾運算來決定整個WHERE子句的值是TRUE還是FALSE。只有那些滿足整個WHERE子句的值是TRUE的記錄才出現(xiàn)在結(jié)果表中。圖3.9年齡不大于38歲的記錄例3.38[使用AND運算符進行條件查詢]?在銷售表中,查詢“銷售數(shù)量”小于20的“商品代碼”為T002的記錄。

AND運算符表示邏輯“與”的關(guān)系。當使用AND運算符組合兩個邏輯表達式時,只有當兩個表達式均為TRUE時才返回TRUE。本例代碼如下:

SELECT*

FROM銷售

WHERE銷售數(shù)量<15and商品代碼?=?'T002';運行該代碼,得到的查詢結(jié)果如圖3.10所示。注意:當語句中使用多個邏輯運算符時,將首先計算AND運算符,使用括號也可以改變求值順序。

圖3.10“銷售數(shù)量”小于20的“商品代碼”為T002的記錄例3.39[使用OR運算符進行條件查詢]?在銷售表中,查詢銷售數(shù)量小于15或商品代碼為T003的記錄。

OR運算符實現(xiàn)邏輯“或”的運算關(guān)系。當使用OR運算符組合兩個邏輯表達式時,只要其中一個表達式的條件為TRUE,結(jié)果便返回TRUE。

本例代碼如下:

SELECT*

FROM銷售

WHERE銷售數(shù)量?<?15or商品代碼?=?'T003';運行該代碼,得到的查詢結(jié)果如圖3.11所示。注意:OR運算符的優(yōu)先級低于AND運算符,即在AND運算符之后才對OR運算符求值。不過,使用括號可以更改求值的順序。圖3.11銷售數(shù)量小于15或商品代碼為T003的記錄例3.40[使用NOT運算符進行條件查詢]?在商品表中,查詢非T001的記錄。

NOT運算符實現(xiàn)邏輯“非”的運算關(guān)系,用于對搜索條件的邏輯值求反。代碼如下:

SELECT*

FROM商品

WHERENOT商品代碼?=?'T001';運行該代碼,得到的查詢結(jié)果如圖3.12所示。NOT運算符對緊跟其后的條件取反,在本例中,“NOT商品代碼?=?'T001'?”語句實際上就等價于“商品代碼!=?'T001'”或者“商品代碼?<>?'T001'”語句。注意:NOTNULL的結(jié)果仍為NULL。圖3.12不包含商品代碼為T001的記錄例3.41[基本邏輯運算符的組合使用]?在銷售表中,查詢所有T003和T002商品并且銷售數(shù)量不高于15的銷售記錄。在WHERE子句中,各種邏輯運算符可以組合使用,即AND、OR、NOT運算符可以同時使用。與使用算術(shù)運算符進行運算一樣,使用邏輯運算符也存在運算優(yōu)先級的問題。在這3種邏輯運算符中,NOT運算符的優(yōu)先級最高,而后是AND,最后是OR。本例代碼如下:

SELECT*

FROM銷售

WHERE商品代碼?=?'T003'OR商品代碼?=?'T002'ANDNOT銷售數(shù)量>15;運行該代碼,得到的查詢結(jié)果如圖3.13所示。圖3.13沒有得到預(yù)期的查詢結(jié)果圖3.13所示的查詢結(jié)果,顯然并沒有得到預(yù)期的效果。根據(jù)邏輯運算符的優(yōu)先級順序,WHERE子句中代碼的執(zhí)行過程如下:首先DBMS執(zhí)行NOT運算,即結(jié)果集中的記錄需要滿足銷售數(shù)量不大于15;而后DBMS執(zhí)行AND運算,即結(jié)果集中的記錄需要滿足T002商品且銷售數(shù)量不大于15;最后DBMS執(zhí)行OR運算,即結(jié)果集中的記錄需要滿足T003商品或者滿足T002商品且銷售數(shù)量不大于15。以上查詢結(jié)果出現(xiàn)了本應(yīng)不出現(xiàn)的“T003商品的銷售數(shù)量為18”的記錄,如果要得到正確的結(jié)果,就要使用括號改變運算的順序。代碼如下:

SELECT*

FROM銷售

WHERE(商品代碼?=?'T003'OR商品代碼?=?'T002')ANDNOT銷售數(shù)量>15;運行該代碼,即得到了正確的查詢結(jié)果,如圖3.14所示。注意:當OR運算符和AND運算符同時運用時,可以不考慮其默認的優(yōu)先級順序,而是采用括號()來實現(xiàn)需要的執(zhí)行順序,這樣可以增強程序的可讀性。圖3.14得到預(yù)期的查詢結(jié)果●使用限定數(shù)據(jù)范圍——BETWEEN進行查詢在WHERE子句中,使用BETWEEN關(guān)鍵字可以更方便地限制查詢數(shù)據(jù)的范圍。使用NOTBETWEEN關(guān)鍵字查詢也可以限定數(shù)據(jù)范圍之外的記錄。語法格式可表示如下:表達式[NOT]BETWEEN表達式1AND表達式2;比如,選擇范圍在10~100之間的數(shù),采用BETWEEN運算符可以表示為

BETWEEN10AND100例3.42

查詢在1970和1971年出生的營業(yè)員的姓名,出生年月和聯(lián)系電話。本例代碼如下:

SELECT姓名,出生年月,聯(lián)系電話

FROM營業(yè)員

WHEREleft(出生年月,4)BETWEEN1970AND1971;運行該代碼,即得到了正確的查詢結(jié)果,如圖3.15所示。使用BETWEEN限制查詢數(shù)據(jù)范圍時同時也包括了邊界值,而使用NOTBETWEEN進行查詢時沒有包括邊界值。也就是說,BETWEEN表達式可以用含有“>=”和“<=”的邏輯表達式來代替;NOTBETWEEN表達式可以用含有“>”和“<”的邏輯表達式來代替。圖3.15在1970和1971年出生的營業(yè)員的記錄●使用限制檢索數(shù)據(jù)的范圍——IN進行查詢

IN與BETWEEN關(guān)鍵字一樣,可以方便地限制檢索數(shù)據(jù)的范圍,靈活使用IN關(guān)鍵字,可以用簡潔的語句實現(xiàn)結(jié)構(gòu)復(fù)雜的查詢。語法格式可表示如下:表達式[NOT]IN(表達式1,表達式2[,…表達式n])其中,所有的條件在IN運算符后面羅列,并以括號()括起來,條件中間用逗號分開。當要判斷的表達式處于括號中列出的一系列值之中時,IN運算符求值為TRUE。例3.43

在銷售表中,查詢工號為001、003和004的銷售員的銷售記錄。本例代碼如下:

SELECT*FROM銷售WHERE工號IN('001','003','004');運行該代碼,得到的查詢結(jié)果如圖3.16所示。在多數(shù)情況下,OR運算符與IN運算符可以實現(xiàn)相同的功能。但使用IN運算符更為簡潔,特別是當選擇的條件很多時,只需在括號內(nèi)用逗號間隔各條件即可,其運行效率也比OR運算符要高。IN運算符后面所有的條件也可以是另一條SELECT語句,即子查詢。這在后面的章節(jié)中會有詳細介紹。圖3.16工號為001、003和004的銷售員的銷售記錄●使用模糊查詢——LIKE進行查詢實際上,當查詢條件不很精確時,需要根據(jù)一些并不確切的線索來搜索信息。采用LIKE子句可以進行這類模糊搜索。語法格式可表示如下:表達式[NOT]LIKE條件

LIKE子句在大多數(shù)情況下會與通配符配合使用。SQLSERVER提供了4種通配符來實現(xiàn)復(fù)雜的模糊查詢條件,如表3.28所示。注意:通配符只有在LIKE子句中才有意義,否則通配符會被當作普通字符處理。表3.28通配符列表例3.44[使用“%”通配符進行任意字符串匹配的模糊查詢]?在商品表中,查詢商品名稱中含有“彩電”字符串的所有商品記錄?!?”通配符表示任意字符的匹配,且不計字符的多少。例如,“電器%”表示匹配以字符串“電器”開頭的任意字符串;“%電器”表示匹配以字符串“電器”結(jié)尾的任意字符串;“%電器%”表示匹配含有字符串“電器”的任意字符串。本例代碼如下:

SELECT*FROM商品WHERE商品名稱LIKE'%彩電%';運行該代碼,得到的查詢結(jié)果如圖3.17所示。商品名稱中所有含有“彩電”字符串的記錄均出現(xiàn)在結(jié)果表中,而不論其在商品名稱中的位置。圖3.17商品名稱中含有“彩電”字符串的商品記錄例3.45[使用“%”通配符指定開頭或結(jié)尾字符匹配的模糊查詢]在營業(yè)員表中,查詢所有姓張的營業(yè)員的姓名、工號。本例代碼如下:

SELECT姓名,工號

FROM營業(yè)員

WHERE姓名LIKE'張%';運行該代碼,得到的查詢結(jié)果如圖3.18所示。圖3.18所有姓張的營業(yè)員的記錄例3.46

[使用“%”通配符實現(xiàn)排除查詢]?在營業(yè)員表中,查詢所有不姓張的營業(yè)員的記錄,即姓名中不能以“張”字符開頭。本例代碼如下:

SELECT*

FROM營業(yè)員

WHERE姓名NOTLIKE'張%';運行該代碼,得到的查詢結(jié)果如圖3.19所示。圖3.19不姓張的營業(yè)員的記錄例3.47

[使用“_”通配符實現(xiàn)模糊查詢]在營業(yè)員表中,查詢姓“張”且全名為兩個漢字的營業(yè)員的記錄。與“%”通配符不同,“_”通配符只能匹配任何單個字符。例如,“張

”表示將查找以“張”開頭的所有兩個漢字的字符串(“張杰”、“張雅”等)。若要表示兩個字符的匹配,需要使用兩個“_”通配符,即寫成“__”。本例代碼如下:

SELECT*

FROM營業(yè)員

WHERE姓名LIKE'張_';運行該代碼,得到的查詢結(jié)果如圖3.20所示。圖3.20姓“張”且全名為兩個漢字的營業(yè)員的記錄例3.48

[同時使用“_”和“%”通配符實現(xiàn)模糊查詢]在營業(yè)員表中,查詢姓名中第2個字為“文”的營業(yè)員的記錄。本例代碼如下:

SELECT*

FROM營業(yè)員

WHERE姓名LIKE'_文%';運行該代碼,得到的查詢結(jié)果如圖3.21所示。圖3.21姓名中第2個字為“文”的營業(yè)員的記錄●使用ESCAPE關(guān)鍵字定義轉(zhuǎn)義字符使用LIKE進行模糊查詢時,當“%”、“_”符號單獨出現(xiàn)時,就會被認為是通配符。但有時可能需要搜索包含一個或多個特殊通配符的字符串。例如,數(shù)據(jù)庫表中可能存儲含百分號“%”的折扣值。若要搜索作為字符而不是通配符的百分號,必須使用ESCAPE關(guān)鍵字和轉(zhuǎn)義符。如下面的語句:

LIKE'%T%'ESCAPE'T'以上表達式中使用了ESCAPE關(guān)鍵字定義了轉(zhuǎn)義字符“T”,這樣,T就成為轉(zhuǎn)義字符,將字符串“%T%”中的第二個百分符(%)作為實際值,而不是通配符。但是,第一個百分符“%”仍然被看做是通配符,因此滿足該查詢條件的字符串為所有以“%”結(jié)尾的字符串。

3)排序查詢結(jié)果

SELECT語句獲得的數(shù)據(jù)一般是沒有排序的(使用DISTINCT關(guān)鍵字除外)。在SQL語言中,使用ORDERBY子句對查詢的結(jié)果進行排序?!窕九判颉狾RDERBY

ORDERBY子句可以指定在SELECT語句返回的列的順序。語法格式可表示如下:

ORDERBY表達式1[ASC|DESC][,表達式2[ASC|DESC][,…n]]其中,表達式是用于排序的列。該語句可用于多列排序,各列在OR

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論