數(shù)據(jù)庫(kù)筆記(十)——關(guān)系代數(shù)

基本運(yùn)算

每一種基本運(yùn)算的結(jié)果都是一個(gè)新的關(guān)系,可以用這個(gè)關(guān)系繼續(xù)參與運(yùn)算,借此便可進(jìn)行復(fù)雜的運(yùn)算

  • 選擇運(yùn)算(select)==>相當(dāng)于SQL語(yǔ)句中的WHERE子句的職能

    • 格式:σ選擇謂詞(關(guān)系)

    • 舉個(gè)栗子:
      • σSAL>1000(EMP)

      • 上式表示取出查詢工資大于1000的所有員工的信息

      • 等價(jià)于下面的SQL語(yǔ)句

      SELECT *
      FROM EMP
      WHERE SAL > 1000
      
    • 選擇謂詞的分類
      • 比較:=、≠、<、≤、>和≥
      • 連詞:and(∧)、or(∨)和not(?)==>可以將多個(gè)謂詞合并成一個(gè)大的謂詞
      • 可以包括兩個(gè)屬性(字段的比較):σCOMM>SAL(EMP)表示抽成大于工資的人
  • 投影運(yùn)算(project)==>相當(dāng)于SQL語(yǔ)句中的SELECT子句的職能

    • 格式:∏字段序列(關(guān)系)

    • 舉個(gè)栗子
      • ENAME,SAL(EMP)

      • 上式表示查看所有員工的姓名和工資

      • 等價(jià)于下面的SQL語(yǔ)句

      SELECT ENAME, SAL
      FROM EMP
      
  • 關(guān)系的組合運(yùn)算==>就像SQL中select、where子句那樣的組合效果

    • 舉個(gè)栗子
      • ENAME,SALSAL>1000(EMP))

      • 上面的式子求出了所有工資大于1000的員工的名字和工資(實(shí)際上就是將σSAL>1000(EMP)執(zhí)行的結(jié)果當(dāng)做一個(gè)臨時(shí)的關(guān)系,參與了投影運(yùn)算得到的)

      • 等價(jià)于下面的SQL語(yǔ)句

      SELECT ENAME, SAL
      FROM EMP
      WHERE SAL > 1000
      
    • 事實(shí)關(guān)系的組合運(yùn)算就是那么簡(jiǎn)單,分析的時(shí)候把每個(gè)簡(jiǎn)單運(yùn)算的結(jié)果當(dāng)做一個(gè)新的關(guān)系參與后面的運(yùn)算,這樣一層層剝開(kāi)來(lái),再?gòu)?fù)雜的語(yǔ)句也變得容易分析
  • 并運(yùn)算(union)==>相當(dāng)于SQL中UNION關(guān)鍵字的職能

    • 格式:(關(guān)系r)∪(關(guān)系s)

    • 舉個(gè)栗子
      • ENAME,SALSAL>1000(EMP)) ∪ ∏ENAME,SALCOMM>300(EMP))

      • 上面的式子求出了所有工資大于1000或抽成大于300的員工的姓名和工資,等價(jià)于下面的SQL語(yǔ)句

      SELECT ENAME, SAL
      FROM EMP
      WHERE SAL > 1000
      UNION
      SELECT ENAME, SAL
      FROM EMP
      WHERE COMM > 300
      
    • 幾點(diǎn)需要額外注意的
      • 此處的并運(yùn)算是集合運(yùn)算,所以結(jié)果是去重的,結(jié)果集中不存在重復(fù)的元組(而在SQL語(yǔ)句中,指定UNION ALL是可以保留重復(fù)的

      • 關(guān)系r與關(guān)系s必須是同元的,即它們的屬性的數(shù)目要求必須相同(這就和SQL語(yǔ)句中UNION使用的時(shí)候要求上下兩個(gè)語(yǔ)句的字段數(shù)相同是一樣的意思)

      • 關(guān)系r和關(guān)系s對(duì)應(yīng)位置的屬性域應(yīng)該是類型兼容的(同樣和SQL中UNION使用時(shí),每個(gè)對(duì)應(yīng)位置字段類型兼容是一樣的意思)

  • 集合的差運(yùn)算(set-defference)==>相當(dāng)于SQL語(yǔ)句中的EXCEPT

    • 格式:(關(guān)系r)-(關(guān)系s)

    • 舉個(gè)栗子
      • ENAME,SALSAL>1000(EMP)) - ∏ENAME,SALCOMM>300(EMP))
      • 上面的式子表示工資大于1000但抽成不大于300的員工的姓名和工資,等價(jià)于下面的SQL語(yǔ)句
      SELECT ENAME, SAL
      FROM EMP
      WHERE SAL > 1000
      EXCEPT
      SELECT ENAME, SAL
      FROM EMP
      WHERE COMM > 300
      
    • 幾點(diǎn)需要額外注意的
      • 此處的注意同上面的并運(yùn)算的注意事項(xiàng)
  • 笛卡爾積運(yùn)算(Cartesian-product)==>等價(jià)于SQL語(yǔ)句中兩個(gè)表進(jìn)行笛卡爾積(全匹配)得到的結(jié)果,即SQL中進(jìn)行多表連接時(shí)不指定連接條件的情況

    • 格式:(關(guān)系r)×(關(guān)系)

    • 舉個(gè)栗子:
      • EMP × DEPT
      • 上面的式子表示兩個(gè)表進(jìn)行全匹配,等價(jià)于下面的SQL語(yǔ)句
      SELECT *
      FROM EMP, DEPT
      
    • 下面兩個(gè)式子是等價(jià)的
      • ENAME,DNAMEEMP.DEPTNO=DEPT.DEPTNOJOB="MANAGER"(EMP×DEPT)))
      • ENAME,DNAMEEMP.DEPTNO=DEPT.DEPTNO((σJOB="MANAGER"(EMP))×DEPT)
      • 下面是對(duì)這兩個(gè)式子的SQL轉(zhuǎn)化,轉(zhuǎn)化之后就一目了然了
        -- 對(duì)應(yīng)第一個(gè)式子
        SELECT ENAME, DNAME
        FROM EMP JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO
        WHERE JOB = 'MANAGER'
        
        -- 對(duì)應(yīng)第二個(gè)式子
        SELECT ENAME, DNAME
        FROM DEPT JOIN (SELECT *
                        FROM EMP
                        WHERE JOB = 'MANAGER')
                  ON EMP.DEPTNO = DEPT.DEPTNO
        
  • 更名運(yùn)算(rename)==>等價(jià)于SQL語(yǔ)句中as的職能

    • 格式:ρX(A1,A2,...,An)(E)==>表示的是將關(guān)系E更名為X,Ai表示的是給E的第i個(gè)字段指定別名

    • 舉個(gè)栗子
      • ENAME,DNAMEe.DEPTNO=d.DEPTNOJOB="MANAGER"e(EMP)×ρd(DEPT))))
      • 上面式子含義就不解釋了,是上面舉的栗子,只是引入了更名運(yùn)算符,它等價(jià)于下面的SQL語(yǔ)句
      SELECT ENAME, DNAME
      FROM EMP e JOIN DEPT d ON e.DEPTNO = d.DEPTNO
      WHERE JOB = 'MANAGER'
      
  • 來(lái),學(xué)習(xí)完上面的基本運(yùn)算,來(lái)做個(gè)實(shí)際的栗子,要求找到員工表中的最高工資(因?yàn)槟壳斑€沒(méi)有介紹類似SQL中組函數(shù)的操作,后面會(huì)介紹。所以通過(guò)以下方式來(lái)實(shí)現(xiàn))

    • step1: 找到所有不是最高工資的人
      • e1.SALe1.sal < e2.sale1(EMP)×ρe2(EMP)))
    • step2: 用所有的員工減去上面的員工,即得到最高工資
      • SAL(EMP) - ∏e1.SALe1.sal < e2.sale1(EMP)×ρe2(EMP)))
  • 在書寫關(guān)系運(yùn)算表達(dá)式的時(shí)候可以用序列號(hào)代替字段名(但是不直觀,不常用,一般不用)

    • 舉個(gè)栗子
      • $6$6 < $14(EMP×EMP))
      • 等價(jià)于下面的運(yùn)算
      • e1.SALe1.sal < e2.sale1(EMP)×ρe2(EMP)))

附加運(yùn)算

附加運(yùn)算是由基本運(yùn)算組成的,不能增強(qiáng)基本運(yùn)算的運(yùn)算能力,但是能簡(jiǎn)化運(yùn)算

  • 集合交運(yùn)算(intersection)==>相當(dāng)于SQL語(yǔ)句中INTERSECT關(guān)鍵字的職能

    • 格式:(關(guān)系r)∩(關(guān)系s)

    • 因?yàn)榧辖贿\(yùn)算是可以由前面的基本運(yùn)算組合產(chǎn)生的,所以把它歸到附加運(yùn)算
      • A ∩ B <=> A - (A - B)
    • 舉個(gè)栗子
      • ENAME,SALSAL>1000(EMP)) ∩ ∏ENAME,SALCOMM>300(EMP))
      • 上面的式子表示工資大于1000并且抽成大于300的員工的姓名和工資,等價(jià)于下面的SQL語(yǔ)句
      SELECT ENAME, SAL
      FROM EMP
      WHERE SAL > 1000
      INTERSECT
      SELECT ENAME, SAL
      FROM EMP
      WHERE COMM > 300
      
  • 自然連接(natural join)==> 相當(dāng)于SQL語(yǔ)句中的NATURAL JOIN

    • 格式:(關(guān)系)?(關(guān)系)

    • 自然連接的形式化定義

      • r,s是兩個(gè)關(guān)系
      • R,S是上面兩個(gè)關(guān)系對(duì)應(yīng)的關(guān)系模式(其實(shí)就是上述兩個(gè)關(guān)系各自的屬性列表)
      • R ∩ S 表示r和s的同名屬性列表
      • R ∪ S 表示出現(xiàn)在r或s上的屬性名列表(是一個(gè)集合,不包同名屬性,存在同名屬性會(huì)去重)
      • R - S 表示出現(xiàn)在R上,但不出現(xiàn)在S上的屬性名列表
      • 則可做如下定義
      • r?s = ∏R∪Sr.A1=s.A1 ∧ r.A2=s.A2 ∧ ... ∧ r.An=s.An(r×s)) ,其中 R∩S={A1, A2, ..., An}
    • 舉個(gè)栗子
      • name, course_id(instructor ? teaches)
      • 上面的式子列出了所有老師的名字以及其所授課程的id,等價(jià)于下面的SQL語(yǔ)句
      SELECT name, course_id
      FROM intructor natural join teaches
      

    ps: 兩個(gè)關(guān)系模式執(zhí)行自然連接以后屬性的排布順序:

    • 排在最前面的是兩個(gè)關(guān)系模式相同的屬性
    • 其次是只屬于第一個(gè)關(guān)系模式的屬性
    • 最后是只屬于第二個(gè)關(guān)系模式的屬性

    ?。?!所以所兩個(gè)關(guān)系模式進(jìn)行自然連接以后,總的屬性的個(gè)數(shù)是減少了,具體減少的個(gè)數(shù)等于同名屬性的個(gè)數(shù)

  • theta連接==>是帶限定條件的笛卡爾積

    • 格式:(關(guān)系)?Θ(關(guān)系)

    • 形式化定義:
      • r ?Θ s = σΘ(r × s)
    • 舉個(gè)栗子
      • name, course_id(instructor ?instructor.ID = teaches.ID ∧ instructor.salary > 5000 teaches)
      • 上面的式子表示列出所有工資大于5000的老師的名字以及其所授課程的id, 等價(jià)于下面的SQL語(yǔ)句
      -- 使用 join...on 的時(shí)候 on 后面寫連接條件,然后將其它條件放在where里
      SELECT name, course_id
      FROM instructor join teaches on instructor.ID = teaches.ID
      WHERE instructor.salary > 5000     
      
  • 除運(yùn)算(division)

    這個(gè)在書上沒(méi)講,是老師上課的時(shí)候補(bǔ)充的

    • 格式:(關(guān)系)÷(關(guān)系)

    • 形式化定義:
      R÷S = ∏R∪S( ( ∏R-S(r) × S ) - ∏R-S, S(r) )
    • 解釋起來(lái)挺麻煩的,這邊給出一個(gè)博客鏈接:點(diǎn)我
  • 賦值運(yùn)算

    就是將一個(gè)關(guān)系表達(dá)式的結(jié)果賦值取一個(gè)臨時(shí)的名字,就相當(dāng)于定義了一個(gè)臨時(shí)關(guān)系。這個(gè)操作就相當(dāng)于SQL中with語(yǔ)句的職能

    • 格式: temp_name ← 關(guān)系表達(dá)式

    • 舉個(gè)栗子:
      temp1 ← R × S
      temp2 ← σr.A1=s.A1 ∧ r.A2=s.A2 ∧ ... ∧ r.An=s.An(temp1)
      result = ∏R∪S(temp2)
    • 上面的式子等價(jià)于: result = r?s
  • 外連接運(yùn)算

    • 左外連:?
    • 右外連:?
    • 全外連:?

擴(kuò)展運(yùn)算

擴(kuò)展運(yùn)算是不能用基本的關(guān)系代數(shù)運(yùn)算來(lái)實(shí)現(xiàn)的一類查詢,可以滿足復(fù)雜的查詢需求

  • 廣義投影(Generalized-projection)

    與基本運(yùn)算中的投影運(yùn)算相比,就是多了允許在選擇列表中出現(xiàn)表達(dá)式(在基本運(yùn)算中的投影的選擇列表中只能出現(xiàn)字段)

    • 格式:∏F1, F2, ... , Fn(E)

      • 其中F1, F2, ... , Fn可以是字段或者是表達(dá)式
      • E代表一個(gè)關(guān)系
    • 舉個(gè)栗子:
      • name, sal * 1.2(instructor)

      • 上面的式子表示查出所有老師的名字,以及漲了20%以后的工資,等價(jià)于下面的SQL語(yǔ)句

      SELECT name, sal * 1.2
      FROM instructor
      
  • 聚集函數(shù)(Aggregation function)

    聚集函數(shù)的符號(hào)表示是用書寫體G,這邊就直接用G指代了

    聚集函數(shù)是輸入值的一個(gè)匯聚,以多個(gè)值作為輸入,將一個(gè)單一的值作為返回結(jié)果

    多重集:使用聚集函數(shù)對(duì)其進(jìn)行操作的匯集中,一個(gè)值可以出現(xiàn)多次,值出現(xiàn)的順序是無(wú)關(guān)緊要的。這樣的匯集稱為多重集(就比方說(shuō)統(tǒng)計(jì)一個(gè)員工表中員工的數(shù)量,然后我們通過(guò)統(tǒng)計(jì)員工的名字來(lái)統(tǒng)計(jì),即便是同名的員工我們也是計(jì)算的)

    • 格式: G1, G2, ... , GnGF1(A1), F2(A2), ..., Fn(An)(E)

      • 其中前面的G1, G2, ... , Gn表示的是分組條件
      • 后面的F1(A1), F2(A2), ..., Fn(An)是聚集函數(shù)表達(dá)式列表
      • Fi(i = 1, 2, ..., n)表示聚集函數(shù):sum、count、average、max、min
      • A1, A2, ... , An代表字段
    • 舉個(gè)栗子:
      • A1, A2Gsum(A3)(∏A1, A2, ..., AnP(r1×r2×...×rm)) )
      • 等價(jià)于下面的SQL語(yǔ)句
      SELECT A1, A2, sum(A3)
      FROM r1, r2, ..., rm
      WHERE P
      GROUP BY A1, A2
      
    • 上面的聚集函數(shù)在進(jìn)行計(jì)算的時(shí)候采用的都是多重集,也就是相同的值可以多次重復(fù)計(jì)算(也就是在執(zhí)行聚集函數(shù)的時(shí)候是不去重計(jì)算),如果要去重計(jì)算的話就要采用下面的幾個(gè)函數(shù)寫法
      • sum_distinct
      • count_distinct
      • averag_distinct
      • max_distinct
      • min_distinct
    • 舉個(gè)栗子:
      • A1, A2Gsum_distinct(A3)(∏A1, A2, ..., AnP(r1×r2×...×rm)) )
      • 上面的式子等價(jià)于下面的SQL語(yǔ)句
      SELECT A1, A2, sum(distinct A3)
      FROM r1, r2, ..., rm
      WHERE P
      GROUP BY A1, A2
      
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.簡(jiǎn)介 數(shù)據(jù)存儲(chǔ)有哪些方式?電子表格,紙質(zhì)文件,數(shù)據(jù)庫(kù)。 那么究竟什么是關(guān)系型數(shù)據(jù)庫(kù)? 目前對(duì)數(shù)據(jù)庫(kù)的分類主要是...
    喬震閱讀 2,035評(píng)論 0 2
  • 5.多表查詢 多表查詢 目的:從多張表獲取數(shù)據(jù) 前提:進(jìn)行連接的多張表中有共同的列 等連接 通過(guò)兩個(gè)表具有相同意義...
    喬震閱讀 1,552評(píng)論 0 0
  • mysql數(shù)據(jù)庫(kù)中 :database : 文件夾table : 數(shù)據(jù)表(數(shù)據(jù)文件) 進(jìn)入mysqlmysql -...
    賦閑閱讀 644評(píng)論 0 0
  • oracle 數(shù)據(jù)庫(kù)的scott帳號(hào)。 <>作為查詢條件時(shí),可以使用!= 來(lái)替換。 SQL> select * f...
    莊棟棟閱讀 2,655評(píng)論 0 0
  • 捉迷藏似乎一直都是小朋友們孜孜不倦喜歡的一種游戲。 我記得我小時(shí)候就很喜歡玩,那個(gè)時(shí)候男生女生在操場(chǎng)上一起玩,很是...
    蘇蘇柳的寫寫畫畫閱讀 309評(píng)論 0 1

友情鏈接更多精彩內(nèi)容