1. 程式人生 > 其它 >《資料庫系統》概念整理

《資料庫系統》概念整理

更新期間圖片可能會裂開,等更新完會統一補上。

注意:下文中的“資料庫”大部分時候都是“資料庫系統”的簡稱,而非嚴格定義下的資料庫。

第1章:引言

資料:描述事物的符號記錄,資料庫的基本物件。

資料庫:長期儲存在計算機內、有組織的、可共享的大量資料集合。

資料庫管理系統:由一個互相關聯的資料的集合和一組用以訪問這些資料的程式組成,是位於使用者與作業系統之間的一層資料管理軟體。

資料庫系統:在計算機系統中引入資料庫後的系統,由資料庫、資料庫管理系統、應用系統(及其開發工具) 、資料庫管理員(和使用者)構成。

檔案處理系統的弊端:資料的冗餘和不一致、資料訪問困難、資料孤立、完整性問題、原子性問題、併發訪問異常、安全性問題

資料模型:資料庫結構的基礎。有關係模型、實體-聯絡模型、基於物件的資料模型、半結構化資料模型四種,網狀模型和層次模型已經被淘汰。

儲存管理器的資料結構:資料檔案(存資料庫)、資料字典(存元資料,是資料庫的資料庫)、索引
資料檔案可以藉助作業系統以檔案形式存在本地,也可以不借助作業系統直接存入磁碟。

資料庫的體系結構:集中式、客戶/伺服器式、分散式

資料庫的層次結構:客戶/伺服器式資料庫可以分為兩或三個部分。兩層-前端/後端,前端直接和後端的資料庫通訊,客戶機上的應用程式通過SQL來呼叫資料庫(JDBC/ODBC);三層-前端/應用伺服器/資料庫伺服器,應用程式的業務邏輯嵌入到應用伺服器內,客戶端通過表單與應用伺服器通訊,應用伺服器與資料庫通訊以訪問資料。

資料庫DBA:模式定義、儲存結構及存取方式定義、模式及物理組織修改、資料訪問授權、日常維護(定期備份等)

資料操縱語言DML(增刪改查)、資料定義語言DDL(create)、資料控制語句DCL(grant, revoke等)

第2章:關係模型

關係模型中,唯一的資料結構是關係,即二維表。

元組:行;屬性:列;屬性的域:某一屬性的取值集合。所有屬性的域都必須是原子的

資料庫模式:資料庫的邏輯設計;資料庫例項:某一時刻資料庫中的資料的快照。關係模式關係例項與之類似。

超碼:一個或多個屬性的集合,這個集合可以唯一地區分出一個元組(一行)

候選碼:最小超碼,可能有多個;主碼:人為選中,作為一行的區分標準的候選碼。

外碼:關係\(r_1\)的屬性中可能包含了關係\(r_2\)的主碼,這個屬性在\(r_1\)上稱作參照\(r_2\)的外碼,\(r_1\)稱作外碼依賴的參照關係\(r_2\)稱作外碼依賴的被參照關係

參照完整性約束:參照關係中的任意元組的特定屬性的取值必須等於被參照關係中某個元組的特定屬性的取值。

查詢語言:使用者用來從資料庫中請求獲取資訊的語言

過程化語言:使用者指導系統對資料庫執行一系列操作來計算結果

非過程化語言:使用者只描述所需資訊,不給出獲取該資訊的具體過程


第345章:SQL

SQL:結構化查詢語言

select, from, where, group by, having, order by, as, like, escape, not like, with, delete from, insert into...values, update...set, case, create table ... as (select...)/like ..., create view ... as

distinct, all, natural join, desc, asc, union, intersect, except, is null, is not null, avg, min, max, sum, count, in, not in, some, all, exists, not exists, unique, join...on/using, (natural) left outer join, right outer join, full outer join

完整性約束:primary key、foreign key約束(參照完整性約束)、not null約束、unique約束、可延遲約束...
完整性約束保證使用者對資料庫的修改不會破壞資料一致性,SQL禁止破壞完整性約束的資料庫更新。

斷言:一個謂詞,表達了我們希望資料庫總能滿足的一個條件。域約束參照完整性約束是斷言的特殊形式。
\(create\ assertion\ <assertion-name>\ check\ <predicate>\)
如果斷言經系統檢測有效,今後只有不破壞斷言的資料庫修改(和斷言)能被允許。

檢視:虛關係,長期儲存查詢結果,使用時重新計算。檢視保證安全性,且更符合特定使用者直覺的個人化的關係集合。資料庫的一個主要目的是為使用者提供資料的抽象檢視,隱藏資料儲存和維護的細節。
一般不允許對檢視關係進行修改,檢視可更新的條件是:

  • from字句中只有一個數據庫關係
  • select子句中只包含關係的屬性名,不包含表示式、聚集或distinct
  • 沒有出現在select中的屬性可以取null(無not null約束,也不構成主碼)
  • 查詢中不含有group by或having
資料型別 含義
char(n) n位定長字串
varchar(n) 變長字串,最大長度為n
int 整數,具體大小與機器有關
numeric(p, d) 定點數,有p位數字,其中d位是小數位
real, double precision 浮點數,雙精度浮點數,精度與機器有關
float(n) 精度至少為n的浮點數
date 日曆時間,年(4位)月日
time(p) 當天時間,時分秒。秒精確到p位小數,預設為0
timestamp(p) date和time(p)的組合,p預設為6
clob(s), blob(s) 字元大物件,二進位制大物件,s可能是x KB, MB, GB
實際儲存偏移量,是大物件定位器

授權\(grant\ P\ on\ TABLE\ to\ USER\) 撤回授權\(revoke\ P\ on\ TABLE\ from\ USER\)
P是許可權,包括select、insert、update、delete、all;也可以通過\(P(a)\)單獨修改使用者在屬性a上的許可權

建立角色\(create\ role\ ROLE;\ grant\ P\ on\ TABLE\ to\ ROLE;\ grant\ ROLE\ to\ USER;\ grant\ ROLE\ to\ ROLE';\)

程式設計語言訪問資料庫的三種方式

  • 動態SQL:JDBC, ODBC(低效易用)
  • 嵌入式SQL:預先寫好SQL語句,嵌入到程式語言中(靜態高效)
  • SQL API:使用專門介面,如OCI(高效,對程式設計師要求高)
public static void JDBCexample(String userid, String passwd) {
    try {
        //裝載JDBC驅動
        Class.forName("oracle.jdbc.driver.OracleDriver");
        //開啟一個連線
        Connection conn = DriverManager.getConnection(
            "jdbc:oracleLthin:@db.yale.edu:1521:univdb", userid, passwd);
        //建立Statement物件
        Statement stmt = conn.createStatement();
        try {
            //執行語句
            stmt.executeUpdate("insert into instructor values('77987', 'Kim', 'Physics', 98000)");
        } catch (SQLException e) {
            System.out.println("Could not insert." + e);
        }
        //處理結果集
        ResultSet rset = stmt.executeQuery(
            "select dept_name, avg(salary) from instructor group by dept_name");
        while(rset.next()) {
            System.out.println(rset.getString("dept_name")+" "+rset.getFloat(2));
        }
        //關閉連線
        stmt.close();
        conn.close();
    } catch (Exception e) {
        System.out.println(e);
    }
}

嵌入式\(EXEC\ SQL\ SQL語句\),如果用到宿主語言的變數,需要先在DECLARE區段中宣告,並在變數前加:

宣告遊標declare cursor: SQL查詢的結果是一個集合,而宿主語言中的變數一次只能儲存一條記錄。為了調和這一矛盾,嵌入式SQL使用遊標(類似指標)來獲取結果集的內容,從而將結果逐行讀出。
select子句宣告遊標,即用一個變數x標識該查詢,此時不執行查詢。當程式執行\(open\ x\)語句時,資料庫執行查詢並將結果存入一個臨時關係中。如果查詢出錯,資料庫會在SQL通訊區的變數中儲存錯誤診斷資訊;如果查詢成功,通過執行\(fetch\ x\ into\ :res1,\ :res2,\ ...(取決於結果集有多少屬性)\)將結果集存入宿主語言的變數中。注意每次fetch只取出一個元組,遊標自動指向下一元組。如果想得到所有結果,需要用迴圈實現。查詢結束後,使用\(close\ x\)刪除臨時關係。

DDL、DCL、update、delete、insert into 都不需要使用遊標。結果只有一行的select子句可以直接將結果存入宿主語言的變數中(此時若結果有多行會出錯)。

觸發器:一條語句,當對資料庫作修改時,它自動被系統執行。設定觸發器必須滿足兩個要求:

  • 指明什麼條件下執行觸發器:分解為引起觸發器被檢測的事件和觸發器執行要滿足的條件
  • 指明觸發器執行時的動作

觸發器何時用與不用:觸發器可以在語句插入時檢查參照完整性,也可以在執行前觸發,避免非法更新、插入、刪除。但觸發器可能加大工作量,且觸發器錯誤會導致語句執行失敗,一個觸發器也可以引發無限的觸發器鏈。因此有其他候選方法時應該避免使用觸發器。

SQL例項


第6章:關係代數

關係代數

過程化查詢語言,基本運算:選擇、投影、並、差、笛卡爾積、更名。關係運算的結果也是關係。

選擇 選出滿足給定謂詞的元組。 \(\sigma _{dept\_name="Physics"}(instructor)\) \(=\ \neq\ \lt\ \gt\)
可以用$\and\ \or\ \neg\ $合併多個謂詞。 \(\sigma _{dept\_name="Physics"\and salary\gt 9000}(instructor)\)

投影 返回修改過的關係,排除不符合要求的屬性。\(\Pi_{ID, name}(instructor)\)

可以將選擇和投影組合起來實現更復雜的運算。\(\Pi_{name}(\sigma _{dept\_name="Physics"}(instructor))\)

將兩個集合並起來。\(\Pi_{name}(\sigma _{dept\_name="Physics"}(instructor))\cup\Pi_{name}(\sigma _{salary>9000}(instructor))\)
要使並運算\(r\cup s\)有意義,必須滿足:1. r和s是同元的,即屬性數量相同;

  1. 對所有的i,r中第i個屬性的域與s中第i個屬性的域相同。

找出一個集合中有而另一個沒有的元組。\(\Pi_{name}(\sigma _{dept\_name="Physics"}(instructor))-\Pi_{name}(\sigma _{salary>9000}(instructor))\)
與並運算相同,差運算也要求同元、相容。

笛卡爾積 將任意兩個關係的資訊組合在一起。\(instructor\times student\)

更名 給關係代數表示式的結果賦上名字。\(\rho_xE\) 返回表示式E的結果,併為其命名為x.
也可以同時為關係中的每個屬性更名,假設E是n元的,\(\rho_{x(A_1,A_2,...A_n)}(E)\)

除了基本關係運算,還有一些附加的、簡化查詢的運算:交、自然連線、賦值、外連線

找出兩個集合的交集。\(\Pi_{name}(\sigma _{dept\_name="Physics"}(instructor))\cap\Pi_{name}(\sigma _{salary>9000}(instructor))\)
與差、並相同,要求同元、相容。

自然連線 對笛卡爾積的結果進行簡化,要求兩個關係中相同屬性的值一致。\(\Pi_{name,ID}(instructor\bowtie teacher\))

\[r\bowtie s=\Pi_{R\cup S}(\sigma_{r.A_1=s.A_1\and r.A_2=s.A_2\and ...\and r.A_n=s.A_n}(r\times s)),其中R\cap S=\{A_1,A_2,...A_n\} \]

賦值 將關係存入一個臨時變數。\(temp1\leftarrow R\times S\)\(temp2\leftarrow \Pi_{A_1}(temp1)\)
賦值運算不會把結果展示給使用者,而是將右側表示式結果存入左側變數,以備後續使用。

外連線 自然連線的擴充套件,它會在結果中建立帶空值的元組,保留自然連線中可能丟失的元組。
左外連線、右外連線、全外連線

除了上述運算,還有擴充套件的關係代數運算能實現更高階的查詢。

除運算\(r(R)\)\(s(S)\)是兩個關係,且\(S\subseteq R\)(模式S中每個屬性都在R中),那麼\(r\div s\)是模式R-S上的關係,元組 t 在\(r\div s\)中當且僅當以下條件同時成立:
t 在\(\Pi_{R-S}(r)\)中;對於s中每一個元組\(t_s\),r中都有元組\(t_r\)同時滿足\(t_r[S]=t_s[S],\ t_r[R-S]=t\).

廣義投影 投影的屬性可以是涉及常量的表示式。

聚集\(G\) 對值的集合使用聚集函式,\(G_{sum(salary)}(instructor)\),還有\(min, max, average, count, count_distinct\)等等
如果要對一組元組集合執行聚集函式(group by),表示式為 \(_{dept\_name}G_{sum(salary)}(instructor)\)

元組關係演算

非過程化查詢語言,查詢表達為 \(\{t\ |\ P(t)\}\)

instructor模式:ID, name, dept_name, salary;course模式:dept_name, cid, ID, ...
以下是幾個查詢的例子。

找出工資大於8000的教師的所有屬性:\(\{t\mid t\in instructor\and t[salary]>8000\}\)
找出工資大於8000的教師的ID:\(\{t\mid \exist s\in instructor(t[ID]=s[ID]\and t[salary]>8000)\}\)
找出在2009年秋或2010年春開課的課程號:\(\{t\mid \exist s \in section(t[cid]=s[cid]\and s[year]=2009 \and s[semester]="Fall")\)
\(\or \exist u\in section(t[cid]=u[cid]\and s[year]=2010 \and s[semester]="Spring")\}\)
如果是找出在2009年秋開課,但2010年春不開的課程號,只需將\(\or \exist u\)改為\(\or \neg \exist u\).
找出選了生物系所有課程的學生:\(\{t\mid \exist s \in student(t[ID]=s[ID])\and \forall u \in course(u[dept\_name]="Biology"\Rightarrow \exist r \in takes(t[ID]=r[ID] \and r[cid]=u[cid])) \}\)

域關係演算

\(\{ <x_1,x_2,...x_n>\mid P(x_1,x_2,...x_n)\}\),其中\(x_1,...x_n\)是域變數,P是由原子構成的公式。

找出工資大於8000的教師的ID, name:\(\{<i,n,d,s>\mid <i,n,d,s>\in instructor \and s>8000\}\)
找出物理系所有老師名及他們教的課的課程號:\(\{<n,c>\mid \exist i,a,se,y(<i,a,se,y>\in teaches \and \exist d,s(<i,n,d,s>\in instructor \and d="Physics"))\}\)
找出在2009年秋或2010年春開課的課程號:\(\{<c>\mid \exist a,s,y,b,r,t(<c,a,s,y,b,r,t>\in section\and s="Fall"\and y="2009")\)
\(\or \exist a,s,y,b,r,t(<c,a,s,y,b,r,t>\in section \and s="Spring" \and y="2010")\}\)
找出選了生物系所有課程的學生:\(\{<i>\mid \exist n,d,tc(<i,n,d,tc>\in student)\and \forall ci,ti,dn,cr(<ci,ti,dn,cr>\in course\and dn="Biology"\)
\(\Rightarrow \exist si,se,y,g(<i,ci,si,se,y,g>\in takes)\}\)

表示式的安全性:在域關係中,不恰當的表示式可能導致結果關係變得無限大(取非可能導致結果是所有不存在於原關係中的元組)如 \(\{<i,n,d,s>\mid \neg (<i,n,d,s>\in instructor)\}\)就是一個不安全的表示式。

附加規則:表示式\(\{<x_1,x_2,...x_n>\mid P(x_1, x_2, ...x_n)\}\)是安全的,當以下條件成立:

  • 表示式的元組中所有值都來自\(dom(P)\)
  • 對每個形如\(\exist x(P_1(x))\)的子公式,它為真當且僅當在\(dom(P_1)\)中有某個值使\(P_1(x)\)為真
  • 對每個形如\(\forall x(P_1(x))\)的子公式,它為真當且僅當在\(dom(P_1)\)中有某個值使\(P_1(x)\)為真

第78章資料庫設計

E-R模型

實體-聯絡模型用於表示概念設計。概念模式定義了實體、實體的屬性、實體間的聯絡、實體和聯絡上的約束等。

資料庫設計中要避免的兩個缺陷是冗餘、不完整

實體 是現實世界中有別於其他物件的一個“事物”或“物件”,通過一組屬性表示
實體集 是相同型別的實體的集合
聯絡 是多個實體間的相互關聯,聯絡中也可以有屬性
聯絡集 是相同型別聯絡的集合。實體集\(E_1,E_2,...E_n\)參與聯絡集\(R\)

簡單屬性、複合屬性、單值屬性、多值屬性、派生屬性

非二元的聯絡集:

弱實體集:沒有足夠的屬性形成主碼的實體集。即實體集中可能會有完全相同的元組,無法區分。
弱實體集必須與另一個屬主實體集關聯,弱實體集依賴於強實體集。

E-R圖設計範例:

正規化

關係資料庫設計