關系演算
以數理邏輯中的謂詞演算為基礎
元組關系演算語言ALPHA
由E.F.Codd提出,以數理邏輯中的謂詞演算為基礎
語句
檢索語句(查詢)
GET
更新語句
PUT,HOLD,UPDATE,DELETE,DROP
一、檢索操作
(1) 簡單檢索(即不帶條件的檢索)
(2) 限定的檢索(即帶條件的檢索)
(3) 帶排序的檢索
(4) 帶定額的檢索
(5) 用元組變量的檢索
(6) 用存在量詞的檢索
(7) 帶有多個關系的表達式的檢索
(8) 用全稱量詞的檢索
(9) 用兩種量詞的檢索
(10) 用蘊函(Implication)的檢索
(1)簡單檢索
GET 工作空間名 (表達式)
[例1] 查詢所有被選修的課程號碼。
GET W (SC.Cno)
[例2] 查詢所有學生的數據。
GET W (Student)
(2)限定的檢索
GET 工作空間名(表達式):操作條件
[例3]查詢信息系(IS) 年齡小於20歲的學號和年齡。
GET W (Student.Sno,Student.Sage): Student.Sdept='IS'∧student.Sage<20
[例 補充]查詢選1號課的學生名和成績
GET W (Student.Sname,SC.grade): SC.CNO=1 ∧ Student.Sno=SC.Sno
(3)帶排序的檢索
[例4] 查詢計算機科學系(CS)學生的學號、年齡,結果按年齡降序排序。
GET W (Student.Sno,Student.Sage): Student.Sdept='CS' DOWN Student.Sage
排序關鍵字: UP升序 DOWN降序
(4)帶定額的檢索
[例6] 查詢信息系年齡最大的三個學生的學號及其年齡,結果按年齡降序排序。
GET W (3) (Student.Sno,Student.Sage): Student.Sdept='IS' DOWN Student.Sage
(5)用元組變量的檢索
元組變量: 取值在某關系內元組的量,用於形成查詢條件
定義元組變量
格式: RANGE 關系名 變量名
例如:
RANGE STUDENT X
(6) 用存在量詞的檢索
[例8] 查詢選修2號課程的學生名字。
RANGE SC X GET W (Student.Sname): 存在X (X.Sno=Student.Sno∧X.Cno=2)
查詢語義:查詢這樣的學生名,條件是存在選課元組X,X的學號與該生的學號相等並且X的課號為2(表明該生選了2號課)
記住: 當查詢條件來自工作區以外的關系時, 要使用元組變量和量詞.
先定義元組變量, 在查詢條件中用量詞引入元組變量.
請對比下面兩個查詢
查詢選修2號課程的學生名字。
條件來自工作區外的關系
RANGE SC X GET W (Student.Sname):存在 X(X.Sno=Student.Sno∧X.Cno=2)
查詢選修2號課的學生名和成績
條件來自工作區內的關系
GET W (Student.Sname,SC.grade): Student.Sno=SC.Sno ∧ SC.CNO=2
[例9] 查詢選修了這樣課程的學生學號,其先行課是6號課程。
RANGE Course CX GET W (SC.Sno): 存在 CX (CX.Cno=SC.Cno∧CX.Pcno=6)
查詢CS系選修2號課程的學生名字?
RANGE SC X GET W (Student.Sname): Student.Sdept= 'CS' ∧存在 X (X.Sno=Student.Sno∧X.Cno=2)
第一個條件只用到學生表, 直接給出,第二個條件則需要元組變量和存在量詞來表示了。
[例10]查詢選修了先行課為6號課的課程的學生名
RANGE Course CX RANGE SC SCX GET W (Student.Sname):存在 SCX(SCX.Sno=Student.Sno ∧ 存在 CX(CX.Cno=SCX.Cno∧CX.Pcno=6))
改為前束范式形式:
RANGE Course CX RANGE SC SCX GET W (Student.Sname):存在 SCX 存在 CX (SCX.Sno=Student.Sno ∧ CX.Cno=SCX.Cno ∧ CX.Pcno=6)
(7)帶有多個關系的表達式的檢索
[例11] 查詢成績為90分以上的學生名與課程名。(工作區的關系,不用定義元組變量)
RANGE SC SCX GET W(Student.Sname,Course.Cname): 存在 SCX ( SCX.Sno=Student.Sno ∧ Course.Cno=SCX.Cno ∧ SCX.Grade≥90)
練習
查詢CS系的學生名
GET W(STUDENT.SNAME):STUDENT.SDEPT='CS'
查詢選1號課的學號,成績
GET W(SC.SNO, SC.GRADE):SC.CNO=1
查詢先行課為6的課名
GET W(COURSE.CNAME):COURSE.CPNO=6
查詢選過課的學生名
RANGE SC X
GET W(Student.Sname): 存在 X (X.Sno=Student.Sno)
查詢選1號課的學生名
RANGE SC X GET W(Student.Sname): 存在 X (X.Sno=Student.Sno∧X.Cno=1)
查詢CS系選1號課的學生名
RANGE SC X GET W(Student.Sname): Student.Sdept='CS' ∧ 存在 X (X.Sno=Student.Sno∧X.Cno=1)
查詢被選過的課名
RANGE SC X
GET W(Course.Cname): 存在 X(X.Cno=Course.Cno)
查詢學號為95001學生選的課名
RANGE SC X GET W(Course.Cname):存在 X (X.Cno=Course.Cno∧X.Sno=95001)
查詢CS系學生的課號,成績
RANGE Student X GET W(SC.Cno, SC.Grade):存在 X (X.Sno=SC.Sno ∧ X.Sdept='CS')
查詢選修數據庫原理課的學號,成績
RANGE Course X GET W(SC.Sno, SC.Grade):存在 X (X.Cno=SC.Cno∧X.Cname='數據庫原理')
查詢CS系選修數據庫原理課的學生姓名
RANGE SC SCX RANGE Course CX GET W(Student.Sname): Student.Sdept='CS' ∧ 存在 SCX 存在 CX (SCX.Sno=Student.Sno ∧ CX.Cno=SCX.Cno ∧ CX.Cname='數據庫原理課')
(8)用全稱量詞的檢索
[例12] 查詢不選1號課程的學生名字。查詢語義:查詢這樣的學生,條件是對所有選課元組, 都不表明該生選了1號課(或者與該生學號不同, 或者課號不是1)
RANGE SC SCX GET W (Student.Sname): 任意 SCX ( SCX.Sno≠Student.Sno ∨ SCX.Cno≠1 )
用存在量詞代替全稱量詞
對所有的x,P為真==不存在這樣的x,P不為真
(8)不用全稱量詞的檢索
[例12] 查詢不選1號課程的學生名。
查詢語義:查詢這樣的學生,條件是不存在選課元組,學號與該生學號相同並且課號是1 (表明該生選了1號課)
用存在量詞表示:
RANGE SC SCX GET W (Student.Sname): 不存在 SCX ( SCX.Sno=Student.Sno ∧ SCX.Cno=1 )
對比使用全稱量詞
RANGE SC SCX GET W (Student.Sname): 任意 SCX ( SCX.Sno≠Student.Sno ∨ SCX.Cno≠1 )
練習:改為沒有選。。。。?
查詢選過課的學生名
RANGE SC X
GET W(Student.Sname): 存在 X (X.Sno=Student.Sno)
查詢選1號課的學生名
RANGE SC X GET W(Student.Sname): 存在 X (X.Sno=Student.Sno∧X.Cno=1)
查詢CS系選1號課的學生名
RANGE SC X GET W(Student.Sname): Student.Sdept='CS' ∧ 存在 X (X.Sno=Student.Sno∧X.Cno=1)
查詢沒有選過課的學生名
RANGE SC X
GET W(Student.Sname): 不存在 X (X.Sno=Student.Sno)
查詢沒有選1號課的學生名
RANGE SC X GET W(Student.Sname): 不存在 X (X.Sno=Student.Sno∧X.Cno=1)
查詢CS系沒有選1號課的學生名
RANGE SC X GET W(Student.Sname): Student.Sdept='CS' ∧ 不存在 X (X.Sno=Student.Sno∧X.Cno=1)
題型沒有...,用不存在
(9)用兩種量詞的檢索
[例13] 查詢選修了全部課程的學生姓名。
求解思路:對於STUDENT中的一個學生,
如果對所有的課程元組CX,都存在着SC的元組SCX,表明這個學生選修了CX, 則這個學生屬於查詢范圍。
RANGE Course CX SC SCX GET W(Student.Sname): 任意 CX 存在 SCX(SCX.Sno=Student.Sno ∧ SCX.Cno=CX.Cno)
短語:STUDENT選修了CX課
存在SCX(SCX.Sno=STUDENT.Sno ∧ SCX.Cno=CX.Cno)
存在選課元組(選課元組與STUDENT和CX有關)
(9)用存在量詞代替全稱量詞
求解思路:查詢這樣的學生,條件是不存在這樣的課程這個學生未選
RANGE Course CX SC SCX GET W(Student.Sname): 不存在 CX 不存在 SCX(SCX.Sno=Student.Sno ∧ SCX.Cno=CX.Cno)
短語:STUDENT選修了CX課
存在 SCX(SCX.Sno=STUDENT.Sno ∧ SCX.Cno=CX.Cno)
短語:STUDENT未選修CX課
不存在 SCX(SCX.Sno=STUDENT.Sno ∧ SCX.Cno=CX.Cno)
(10)用蘊函(Implication)的檢索
[例14] 查詢選修了95002學生所選課程的學生學號。
查詢語義:查詢這樣的學生,條件是對所有課程,如果95002選了,則該學生也選修了該課
RANGE Course CX SC SCX SC SCY GET W (Student.Sno): 任意 CX( 存在 SCX (SCX.Sno=95002∧SCX.Cno=CX.Cno) =》存在 SCY(SCY.Sno=Student.Sno∧ SCY.Cno= CX.Cno))
(11)改為不用蘊函
查詢語義:
對所有的課, 95002不選或者該學生選了。
RANGE Couse CX SC SCX SC SCY GET W (Student.Sno): 任意 CX( 不存在 SCX(SCX.Sno='95002'∧SCX.Cno=CX.Cno) 或者 存在 SCY(SCY.Sno=Student.Sno ∧ SCY.Cno= CX.Cno))
(12)改為不用蘊函不用全稱
思路:不存在這樣的課,95002選了並且這個學生未選
RANGE Couse CX SC SCX SC SCY GET W (Student.Sno): 不存在 CX(存在 SCX (SCX.Sno=95002∧SCX.Cno=CX.Cno) ∧ 不存在 SCY(SCY.Sno=Student.Sno ∧ SCY.Cno= CX.Cno))
使用離散數學的證明過程:
圖書管理數據庫練習
圖書管理數據庫有關系模式:
圖書(書號,書名,價格,作者)
讀者(讀者號,姓名,性別,年齡)
借閱(讀者號,書號,借日期,還日期,罰款金額)
用元組關系演算查詢:
1 查詢價格大於50的書名和作者名
2 查詢(一次)罰款金額>20元的讀者名
3 查詢被年齡大於60的讀者借過的書名和作者名
4 查詢看了所有書的讀者名
5 查看了2001號讀者所看過的所有書的讀者號
6 查詢沒有借過書的讀者姓名
1 查詢價格大於50的書名和作者名
GET W(圖書.書名, 圖書.作者): 圖書.價格>50
關系代數?
π 書名,作者名(σ 價格>50(圖書))
2 查詢(一次)罰款金額>20元的讀者名
查詢語義:查詢這樣的讀者,條件是存在借閱元組表明該讀者的罰款金額>20)
RANGE 借閱 借閱X GET W(讀者.姓名): 存在 借閱X (借閱X.讀者號=讀者.讀者號 並且 借閱X.罰款金額>20)
關系代數?
π 姓名(σ 罰款金額>20(借閱 連接 讀者))
3查詢被年齡大於60的讀者借過的書名和作者名
查詢語義:查詢這樣的圖書,條件是存在借閱元組和讀者元組,表明該圖書被年齡大於60的讀者借過
RANGE 讀者 讀者X RANGE 借閱 借閱X GET W(圖書.書名, 圖書.作者): 存在 借閱X 存在 讀者X (借閱X.圖書號=圖書.圖書號 並且 借閱X.讀者號=讀者X.讀者號 並且 讀者X.年齡>60)
關系代數?
π 作者,書名 (σ 年齡者>60 (讀者 連接 借閱 連接 圖書 ))
4 查詢看了所有書的讀者名
(用不存在量詞)
查詢語義:查詢這樣的讀者,條件是不存在這樣的圖書,該讀者未看
RANGE 圖書 圖書X
借閱 借閱X
GET W(讀者.姓名): 不存在 圖書X (不存在 借閱X(借閱X.讀者號=讀者.讀者號 並且 借閱X.圖書號=圖書X.圖書號 ) )
關系代數?
π 姓名(( π 讀者號,書號(借閱) ÷ π 書號(圖書)) 連接 讀者)
5查看了2001號讀者所看過的所有書的讀者名
查詢語義: 查詢這樣的讀者姓名,條件是對所有的圖書, 如果存在借閱X 元組表明2001號讀者借, 則存在借閱Y元組表明該讀者也借
RANGE 圖書 圖書X RANGE 借閱 借閱X RANGE 借閱 借閱Y GET W(讀者.姓名): 任意 圖書X(存在 借閱X(借閱X.圖書號=圖書X.圖書號 並且 借閱X.讀者號=‘2001’ ) =》
存在 借閱Y(借閱Y.讀者號=讀者.讀者號 並且 借閱Y.圖書號=圖書X.圖書號 ))
上題不用全稱和蘊涵實現
查詢語義: 查詢這樣的讀者姓名,條件是不存在這樣的圖書, 2001借並且該讀者不借(存在借閱X 元組表明2001號讀者借並且不存在借閱Y元組表明該讀者借)
RANGE 圖書 圖書X RANGE 借閱 借閱X RANGE 借閱 借閱Y GET W(讀者.姓名): 不存在 圖書X(存在 借閱X(借閱X.圖書號=圖書X.圖書號 並且 借閱X.讀者號=‘2001’ )
不存在 借閱Y(借閱Y.讀者號=讀者.讀者號 並且 借閱Y.圖書號=圖書X.圖書號 ))
關系代數?
π 讀者號,書號(借閱) ÷ π書號(σ 讀者號=2001 (讀者 連接 借閱))
6 查詢沒有借過書的讀者姓名
解題思路: 查詢讀者名, 條件是不存在這樣的借閱X,借閱X的讀者號與該讀者的讀者號相等
GET W(讀者.姓名): 不存在 借閱X(借閱X.讀者號=讀者.讀者號)
關系代數?
π姓名( ( π讀者號 (讀者) - π讀者號 (借閱)) 連接 讀者)
工程供應數據庫練習
供應商-零件-工程-供應數據庫關系模式
S(SNO,SNAME,STATUS,CITY);
P(PNO,PNAME,COLOR,WEIGHT);
J(JNO,JNAME,CITY);
SPJ(SNO,PNO,JNO,QTY);
(1)求供應工程J1的供應商號
關系代數:
投影 SNO(選擇 JNO=‘J1’(SPJ))
關系演算:
GET W (SPJ.SNO):SPJ.JNO=‘J1’
2)求供應工程J1零件P1的供應商號
關系代數:
投影 SNO(選擇 JNO=‘J1’ 並且 PNO=‘P1’(SPJ))
關系演算:
GET W (SPJ.SNO):SPJ.JNO=‘J1’ 並且 SPJ.PNO=‘P1’
(3)求供應工程J1零件為紅色的供應商號SNO
關系代數:
GET W (SPJ.SNO):SPJ.JNO=‘J1’並且 SPJ.PNO=‘P1’
關系演算:
RANGE P PX
GET W(SPJ.SNO): SPJ.JNO=‘J1’ 並且 存在 PX(PX.PNO=SPJ.PNO 並且 PX.COLOR=‘紅’)
(4)求沒有使用天津供應商生產的紅色零件的工程號JNO
關系代數:
投影 JNO(J)-投影 JNO(選擇 CITY=‘天津’ 並且 COLOR=‘紅’(S 連接 SPJ 連接 P))
關系演算:
從J中查詢這樣的JNO, 條件是不存在這樣的供應元組SPJX表明該工程使用了天津生產的紅色零件
GET W(J.JNO): 不存在 SPJX( SPJX.JNO=J.JNO ∧ 存在 SX(SX.SNO=SPJX.SNO∧ SX.CITY=‘天津’) ∧ 存在 PX(PX.PNO=SPJX.PNO ∧ PX.COLOR=‘紅’))
(5)求至少用了供應商S1供應的所有零件的工程號JNO
關系代數:
投影 JNO,PNO(SPJ) 除 投影 PNO (選擇 SNO=‘S1’(SPJ))
從J中查詢這樣的工程號,條件是: 不存在這樣的零件元組PX, S1供應而該工程不用
GET W(J.JNO): 不存在 PX( 存在 SPJX(SPJX.PNO=PX.PNO ∧ SPJX.SNO=‘S1’) ∧ 不存在 SPJY(SPJY.PNO=PX.PNO ∧ SPJY.JNO=J.JNO ))
(6) 查詢使用了全部零件的工程號JNO
關系代數:
投影JNO,PNO(SPJ) 除 投影 PNO (SPJ)
關系演算:
從J中查詢這樣的工程號,條件是:不存在這樣的零件元組PX, 該工程不用
GET W(J.JNO): 不存在 PX( 不存在 SPJY(SPJY.PNO=PX.PNO ∧ SPJY.JNO=J.JNO ))