《數據庫系統概念》讀書筆記,第六章、形式化關係查詢語言

《數據庫系統概念》讀書筆記,第六章、形式化關係查詢語言

  • 引入:

    這一章主要就是從數學角度,給出了三種 形式化語言(關係代數,元祖關係演算,域關係演算) 的定義,他們是各種查詢關係語言的基礎。


  • 關係代數:

    SQL查詢語言就是以關係代數爲基礎的,這種語言強調的是查詢的操作過程,也就是說它是一種過程化查詢語言。所以只需要按照其給定的“查詢結果的過程序列”一步一步完成就可以得到最終需要查詢的內容。
    首先先進行一些基本概念的描述,或者說這一部分是我對於關係代數體系的理解總結

    1. 關係代數一定是“關係”之間的運算,也就是說它的基本運算單位是“關係”。
    2. 對於一個“關係”,它可以看成是一個“元組”的集合,也就是說,很多個結構相同的元組可以組成一個“關係”,關係攜帶的信息就是它的所有元組。
    3. 對於一組代數關係,既然定義了它的基本操作元素(關係),下一步就是要定義基本的運算:選擇、投影、並、集合差、笛卡爾積、更名。
    4. 爲了更加方便的表示運算,我們進一步的封裝了一些附加的關係代數運算:集合交、自然連接、賦值。這些運算都是通過上面的基本運算定義出來的,所以他們都是可以被基本運算所表示,他們之所以出現只是爲了更方便的進行表達。
  1. 還有一些擴展的關係代數運算,這些運算是不能用基本的關係代數運算代替的,比如:廣義投影、聚集。

下面的內容就是對於每一個關係代數運算的具體描述

基礎關係代數運算:

  1. 選擇(σ\sigma
    可以看成一種帶限制的函數,自變量也就是輸入信息就是一組關係x,函數值爲一組新的關係y,y中的元組是x的元組的一個子集,或者說y中的元組是x中所有滿足謂詞限制p的元組。
    • 用途:選出關係中滿足一定條件的元組組成一個新的關係。
    • 表達式形式:σsalary900dept_name=xcx(instructor)\sigma_{salary \le 900 \bigwedge dept\_name='xcx' }(instructor)
  2. 投影運算(Π\Pi
    • 用途:忽略關係中的一部分屬性,只留下需要的屬性,並且保留所有元組。
    • 表達式形式:ΠID,name,salary(instructor)\Pi_{ID,name,salary}(instructor)
  3. 並運算(\bigcup
    • 用途:對於兩個關係,讓他們的元組集合取並,也就是相當於合併兩個相同結構的關係同時保證內部元組的互異性。
    • 表達形式:E1E2E_1 \bigcup E_2
  4. 集合差運算(-
    • 用途:去除 E1E_1 中同時在 E2E_2 元組,更進一步可以看成是爲了去除一個集合中,滿足某些條件的一系列元組。
    • 表達式形式:E1E2E_1- E_2
  5. 笛卡爾積運算(×\times
    • 用途:把兩個關係中的元組任意兩兩組合得到一個新的關係(一般會在繼續進一步的進行選擇運算),特殊的當兩個關係相同的時候,他們進行笛卡爾積運算可以看成一個兩兩比較的過程(經常用於取最大,取最小等)。
    • 表達式形式:E1×E2E_1\times E_2
  6. 更名運算(ρ\rho
    • 用途:爲了避免後面引用時避免歧義,對於一個關係的各個屬性或者關係本身進行更名。
    • 表達式形式:ρx(E)\rho_{x}(E)ρx(A1,A2,...,An)(E)\rho_{x(A_1,A_2,...,A_n)}(E)

附加關係代數運算:

  1. 集合交運算(\bigcap
    • 用途:既然有集合並也就肯定會自然的想到集合交,但是集合交確實可以有上面的基礎運算關係表示。
    • 表達式形式:E1E2E1(E1E2)E_1 \bigcap E_2 \Longleftrightarrow E_1-(E_1-E_2)
  2. 自然連接運算(\bowtie
    • 用途:對於笛卡爾積和選擇運算的組合,因爲很多時候都是要將兩個有一部分相同屬性的關係進行笛卡爾積,並選出他們相同屬性內容完全相同的元組,這時候就可以使用自然連接運算,也就是找出真是存在的所有實體的信息元組。
    • 表達式形式:E1E2ΠE1E2(σE1.A1=E2.A1E1.A2=E2.A2...E1.An=E2.An(E1×E2))E_1 \bowtie E_2 \Longleftrightarrow \Pi_{E_1\bigcup E_2} (\sigma_{E_1.A_1 = E_2.A_1 \bigwedge E_1.A_2 = E_2.A_2 \bigwedge ... \bigwedge E_1.A_n = E_2.A_n}(E_1 \times E_2))
      其中:E1E2={A1,A2,...,An}E_1 \bigcap E_2 = \{A_1,A_2,...,A_n\}
    • 這裏其實強行用表達式描述的話,理解起來會有一點繁瑣,所以還是選擇用簡單的比較容易接受的語言來表述吧。如果不寫謂詞角標則表示,將兩個關係的所有相同屬性上信息相同的元組合並,然後兩個相同的屬性也只保留一個屬性,這樣生成出一個元組的集合就是計算返回的關係。如果有謂詞角標,就選擇兩個屬性笛卡爾
  3. theta連接運算(θ\bowtie_{\theta}
    • 用途:它是自然連接的擴展,用於描述更普遍的笛卡爾積+選擇的結構。謂詞即爲選擇符號的謂詞
    • 表達式形式:E1θE2σθ(E1×E2)E_1 \bowtie_{\theta} E_2 \Longleftrightarrow \sigma_{\theta}(E_1 \times E_2)
      注:θ\theta 是一個謂詞。
  4. 賦值運算(\leftarrow
    • 用途:開臨時關係變量,方便保存也容易理解邏輯結構,避免一個表達式過長
    • 表達式形式:E1E2E_1 \leftarrow E_2
  5. 外連接運算(左外連接、右外連接、全外連接)
    這個實在沒找到 Latex 裏面怎麼表示它的符號,自行查閱吧。看起來就是自然連接符號左邊或者右邊或者看兩邊出兩個橫線。
    • 用途(以左連接運算爲例):考慮實際應用情況,在對兩個元素進行自然連接運算的時候,如果E1的一個元組的某一個屬性,這個屬性在E2中也出現了,但是這個元組的這個屬性的信息在E2關係中,並沒有出現過,那麼這個元組在自然連接運算的時候就被忽略掉了, 這個時候就需要一個左外連接運算,然後讓E1的每一個元組至少在自然連接之後出現一次,然後其對應未知屬性(出現在E2但是沒出現在E1的屬性)值爲空(NULL)。右連接運算同理就是保證E2中的每個元組信息至少出現一次。全連接就是E1,E2都要保證至少出現。

擴展關係代數:

  1. 廣義投影(Π\Pi
    其實就是投影的進一步功能擴展,並部複雜
    • 用途:在投影屬性一欄加入了數值運算功能,提供了元組信息修改功能。(上面的操作都是在對元組進行選擇、重新組合,這時元組是最小的不可分單位,元組的屬性信息不會發生改變)
    • 表達式形式:ΠID,salary/12(instructor)\Pi_{ID,salary/12}(instructor)
  2. 聚集
    聚類函數輸入值得一個彙集,將單一結果返回。
    • 用途:求一組數據的平均值,最大值,數值累加和,不同元素數量等等
    • 表達式形式:G1,G2,...,GnGF1(A1),F2(A2),...,Fm(Am)(E)_{G_1,G_2,...,G_n}G_{F_1(A_1),F_2(A_2),...,F_m(A_m)}(E)
    • 實際應用舉例:Gsum(salary)(instructor)G_{sum(salary)}(instructor)Gcount_distinct(ID)(teachers)G_{count\_distinct(ID)}(teachers)dept_nameGaverage(salary)(instructor)_{dept\_name}G_{average(salary)}(instructor)

附加:關於多重集關係代數

上面的關係都是類似於集合的存在,即必須滿足一個關係中元組的互異性。但是和SQL不同的是,SQL的一個關係可以有多個相同的元組,所以文中又簡單的擴展定義了多重集。後面又依次將基本關係代數運算對應的在多重集上的運算方式進行了定義。


  • 元組關係演算

如果說關係代數過程化的查詢語言,那麼與之對應的元組關係演算就是非過程性的查詢語言。換句話說,他關注的不是“通過怎樣的查詢方法來查到需要查詢的關係(元組集合)”,而是更加關注“如何才能更加清晰的描述出來我需要的元組滿足的性質“。
因爲查詢的是一個元組的集合,所以我們可以猜到,元組關係演算中的查詢表達基本形式:{tP(t)}\{t|P(t)\}
注: tt 表示元組,PP 是謂詞,t[A]t[A] 表示元組 tt 在屬性 AA 上的取值。

  • 引入存在量詞和全稱量詞
    存在量詞:tr(Q(t))\exists t \in r(Q(t)) 表示關係 rr 中存在元組 tt 使得謂詞 Q(t)Q(t) 爲真
    全稱量詞:tr(Q(t))\forall t \in r(Q(t)) 表示對於關係 rr 中所有元組 tt,謂詞 Q(t)Q(t) 爲真
    {ttinstructort[salary]>80000}\{t|t\in instructor \wedge t[salary] > 80000\}{tsinstructor(t[ID]=s[ID]s[salary]>80000)}\{t|\exists s \in instructor(t[ID] = s[ID] \wedge s[salary]>80000)\} 這是引入兩個量詞的關鍵。
    第一個表示的是,查找 instructorinstructor 中的所有滿足條件的元組
    第二個表示的是,只查詢 instructorinstructor 中滿足條件的IDID屬性,因爲 IDID 是唯一對 tt 進行限制的屬性,所以 tt 的模式爲(ID)(ID)
  • 形式化定義
    書中有一套形式化的遞歸形式的定義,這裏不再複述。
  • 表達式的安全性
    最後一個可能產生意外的地方就是,對於這一類的表達式:{t¬(tinstructor)}\{t|\neg (t\in instructor)\},顯然不在 instructorinstructor 中的元組有無限多個,顯然這樣不是我們需要的結果。所以這裏我們引入一個新的概念“PP 的域”記爲 dom(P)dom(P) ,它是 PP 所引用的所有值的集合。嚴格來說,PP 的域就是:PP 中顯式出現的值及名稱出現在 PP 中的那些關係的所有值的集合。所以對於表達式{ttP(t)}\{t| t \in P(t)\},只有它的結果的所有值均來自於 dom(P)dom(P) 時,我們才說這個表達式是安全的。

  • 域關係演算

    域關係演算使用的不再是“元組”作爲對象,而是使用“從屬性域中取值的域變量”作爲對象。對比關係代數是SQL語言的基礎,域關係演算是被廣泛採用的QBE語言的理論基礎。

    • 形式化定義
      {<x1,x2,...,xn>P(x1,x2,...,xn)}\{<x_1,x_2,...,x_n>|P(x_1,x_2,...,x_n)\}
      x1,x2,...,xnx_1,x_2,...,x_n代表域變量,PP 代表原子構成的公式。
      原子構造公式略(和上一個定義類似,遞歸結構定義)
      另加一個縮寫:a(b(c(P(a,b,c))))\exists a(\exists b( \exists c(P(a,b,c))))縮寫爲a,b,c(P(a,b,c))\exists a,b,c(P(a,b,c))
    • 表達式規則
      還是全憑藉感覺吧,書中也是給出了這樣幾個例子,首先先在這裏重複列出這幾個例子,最後在簡單說一下對於這個規則的理解總結。
      1. 例子
        • 找出工資超過 80 000 的教師的 IDnamedept_namesalaryID、name、dept\_name、salary
          {<i,n,d,s><i,n,d,s>instructors>80000)}\{<i,n,d,s>|<i,n,d,s>\in instructor \wedge s>80 000)\}
        • 找出工資超過 80 000 的教師的 IDID
          {<i>n,d,s(<i,n,d,s>instructors>80000)}\{<i>|\exists n,d,s(<i,n,d,s>\in instructor \wedge s>80 000)\}
        • 找出在物理系的所有教師的姓名,以及他們教授的所有課程的 course_idcourse\_id
          {<n,c>i,a,se,y(<i,c,a,se,y>sectiond,s(<i,n,d,s>instructord="physics))}\{<n,c>|\exists i,a,se,y(<i,c,a,se,y>\in section \wedge \exists d,s(<i,n,d,s>\in instructor \wedge d="physics))\}
        • 找出在2009年秋季學期或者2010年春季學期或者這兩個學期都開設的所有課程的集合 course_idcourse\_id
          {<c>a,s,y,b,r,t(<c,a,s,y,b,r,t>sections="Fall"y="2009")a,s,y,b,r,t(<c,a,s,y,b,r,t>sections="Spring" wedgey="2010")}\{<c>|\exists a,s,y,b,r,t(<c,a,s,y,b,r,t>\in section \wedge s="Fall"\wedge y="2009") \vee \exists a,s,y,b,r,t(<c,a,s,y,b,r,t>\in section \wedge s="Spring" \ wedge y = "2010") \}
        • 找出選了生物系開設的全部課程的所有學生 IDID
        • {<i>n,d,tc(<i,n,d,tc>student)ci,ti,dn,cr(<ci,ti,dn,cr>coursedn="Biology"si,se,y,g(<i,ci,si,se,y,g>takes))}\{<i>|\exists n,d,tc(<i,n,d,tc>\in student ) \wedge \forall ci,ti,dn,cr(<ci,ti,dn,cr>\in course \wedge dn="Biology"\Longrightarrow \exists si,se,y,g(<i,ci,si,se,y,g>\in takes))\}
      2. 理解總結
        首先查詢的元組的屬性就是豎線左邊的尖括號中的內容,然後類似於select語句的層層限制即可,注意這裏面的每個變量都表示的是一個域(取值集合)。
    • 表達式安全性
      同上元組關係演算的相關要求。(未具體閱讀

  • 最後小結

    首先對於關係代數表達式的描述是比較清晰的,因爲是SQL語句的基礎嘛,然後對於後面的元組關係演算和域關係演算,多加練習吧。。。。
    最後再從表達能力的角度考察:
    基本關係代數運算、限制在安全表達式範圍內的元組關係演算、限制在安全表達式範圍內的域關係演算。這三者的表達能力是相同的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章