数据库基本知识学习
第一章 基本知識
數據和信息
信息:關于現實世界事物存在方式和運動狀態的反映。
數據:通常指用符號記錄下來的、可以識別的信息。
數據處理和數據管理
數據處理是指從某些已知的數據出發,推導加工出一些新的信息。
數據管理是指數據的收集、整理、存儲、維護、檢索、傳送等操作。這部分操作是數據處理業務的基本環節,而且是任何數據處理業務中必不可少的共有部分。
數據庫基本術語
數據庫(DB):長期存儲在計算機內、有組織的、統一管理的相關數據的集合。
數據庫管理系統(DBMS):位于用戶和操作系統之間的一層數據管理軟件。
數據庫系統(DBS):實現有組織地、動態地存儲大量關聯數據、方便多用戶訪問的計算機硬件、軟件和數據資源組成的系統。
數據庫技術:與數據庫的結構、存儲、設計、管理和使用的相關技術。
數據存儲方法的演化歷史:磁盤、卡片和紙帶發展到磁盤,同時磁盤容量出現飛速增長。
數據庫技術的發展經歷了三個階段:手工管理階段、文件系統階段和數據庫階段。
手工管理階段:在20世紀50年代以前,外存只有磁帶、卡片和紙帶,還沒有直接存取設備,沒有操作系統,沒有管理數據的軟件,也沒有文件的概念。數據量少,由用戶自己管理,且數據沒有組織結構,是面向應用的,依賴于應用程序,不能獨立存在。
文件系統階段:50年代后期到60年代中期,出現了磁鼓、磁盤等存儲設備,于是數據被組織成獨立的數據文件,這樣數據以“文件”形式長期保存在外部存儲器的磁盤上,系統通過文件名訪問,對文件里的記錄進行存取,并可對文件中的記錄進行增刪改。文件系統實現了記錄的結構化,即給出了記錄間各種數據的關系,使得數據的邏輯結構與物理結構有了區別。文件組織也已經多樣化。數據不再屬于某個特定的程序,可以重復使用。
但文件從整體上看仍是無結構的,數據共享性、獨立性差,數據之間聯系弱,數據不一致,且有大量冗余,所以管理和維護的代價很大。
數據庫階段:60年代后期,出現了數據庫這樣的數據管理技術。1968年IBM推出層次模型的IMS系統。1969年CODASYL組織發布了DBTG報告,總結了當時各種數據庫,提出網狀模型。可以說,層次數據庫是數據庫系統的先驅,而網狀數據庫則是數據庫概念、方法、技術的奠基者。1970年IBM的E.F.Codd連續發表論文,提出關系模型,奠定了關系數據庫的理論基礎。
數據庫的特點有:采用數據模型表示復雜的數據結構;有較高的數據獨立性;數據庫系統為用戶提供了方便的用戶接口;數據庫系統提供了數據庫的并發控制、數據庫的恢復、數據的完整性、數據安全性這四方面的數據控制功能。
除了關系數據庫,如今還有一些高級數據庫,比如分布式數據庫系統、對象數據庫系統、網絡數據庫系統。
分布式數據庫通常使用位于不同的地點的較小的計算機系統,通過網絡連接構成完整的、全局的大型數據庫。每臺計算機有DBMS的一份完整拷貝,且具有自己局部的數據庫。
對象數據庫是用以對象形式表示信息的數據庫。對象數據庫的管理系統稱為ODBMS或OODBMS。
網絡數據庫由數據和資源共享這兩種方式結合在一起而成,也稱Web數據庫。它以后臺(遠程)數據庫為基礎,加上一定的前臺(本地計算機)程序,通過瀏覽器完成數據的存儲、查詢等操作。
數據庫系統的體系結構
數據庫系統的結構常采用三級模式結構:外模式、概念模式、內模式。
概念模式簡稱為模式,它表示了對數據的全局邏輯級的抽象級別,是數據庫中全部數據的整體邏輯結構的描述。它由若干個概念記錄類型組成,還包含記錄間聯系、數據的完整性、安全性等要求。在實現中,它可以對應于所有的表格。
內模式也稱存儲模式,表示了對數據的物理級的抽象級別。它是數據庫中全體數據的內部表示或底層描述,是數據庫最低一級的邏輯描述,它描述了數據在存儲介質上的存儲方式和物理結構,對應著實際存儲在外存儲介質上的數據庫。它包括記錄類型、索引、文件的組織等,用內模式描述語言來描述、定義。
外模式也稱子模式,表示了對數據的局部邏輯級的抽象級別。它對應于用戶級,是用戶與數據庫系統的接口,是用戶用到的那部分數據的描述。在實現中可以對應于視圖。
三級模式間存在二級映象:
外模式/概念模式映象:局部邏輯級和全局邏輯級的一級映象,提供了邏輯獨立性。這樣在修改表格時,只需要相應修改映象,而用戶程序不會受到影響。
概念模式/內模式映象:全局邏輯級和物理級的一級映象,提供了物理獨立性。這樣在進行數據庫遷移時,比如從mysql到sqlserver,表格并不需要發生變化。
DBMS用于管理數據庫。應用程序向DBMS發送請求,DBMS則向DB發出底層指令。DB向DBMS返回數據(查詢結果),DBMS對數據進行處理并返回給應用程序數據(處理結果)。
DBMS的主要功能有:數據庫的定義功能、數據庫的操縱功能、數據庫的保護功能(數據庫的恢復、數據庫的并發控制、數據完整性控制和數據安全性控制)、數據庫的維護功能和數據字典(存放數據庫的信息,其用途為描述數據,比如一個表的創建者信息,創建時間信息,所屬表空間信息,用戶訪問權限信息等)。
數據庫系統的組成:數據庫、硬件、軟件(DBMS、OS、開發工具等)和數據庫管理員。
數據庫系統的用戶角色有:
DBA(Database Administrator):是控制數據庫整體結構的一組人員,負責DBS的正常運行,承擔創建、監控和維護數據庫的責任。它的職責有:定義模式、定義內模式、與用戶的聯絡(包括定義外模式、應用程序的設計、提供技術培訓等專業服務)、定義安全性規則和對用戶訪問的數據庫進行授權、定義完整性規則及監督數據庫的運行、數據的轉儲和恢復工作。
專業用戶:使用專用的數據庫查詢語言操作數據的計算機工作者。
應用程序員:使用主語言和DML語言(Data Manipulation Language,SQL的分類之一,包括:INSERT、UPDATE、DELETE。)編寫應用程序的計算機工作者。
終端用戶:使用應用程序的非計算機人士。
第二章 數據模型
數據模型的概念
能表示實體類型及實體間聯系的模型稱為“數據模型”。
數據模型分為兩類:概念數據模型、輯數據模型和物理數據模型。
概念數據模型(Conceptual Data Model)貼近于現實世界,它獨立于計算機系統,完全不涉及信息在計算機中的表示,只是用來描述某個特定組織所關心的信息結構。
最常用的概念數據模型是E-R(Entity-Relationship)模型,即實體-聯系模型。它的數據描述有:
實體:客觀存在,可以互相區別的事物。
實體集:性質相同的同類實體的集合。
屬性:實體的特性。
實體標識符。
聯系:實體之間的相互聯系。
ER模型可以用ER圖來表示,它看起來如下:
ER圖有三個基本成分:矩形框,用于表示實體類型(考慮問題的對象);菱形框,用于表示聯系類型;橢圓形框,用于表示實體和聯系類型的屬性,實體的主鍵屬性里文字下方應該有下劃線。從上圖可以看到實體和聯系都可以有屬性。一般說來,ER圖里實體都是名詞,而聯系都是動詞。
ER圖的優點有:簡單、容易理解,真實反映用戶的需求;與計算機無關,用戶容易接受。
與一個聯系有關的實體集個數被稱為元數。一個聯系可以是一元聯系、二元聯系或多元聯系。上圖展示的聯系就是二元聯系。根據實體參與的數量,二元聯系又可分為一對一(1:1,乘客和座位)、一對多(1:N,車間和工人)和多對多(M:N,學生和課程)。上表中的聯系上m和n表示多對多的關系。一元聯系的一個例子是零件的組合關系,一個零件可以用若干子零件組成。
屬性的分類
根據屬性的可分性,屬性有基本屬性和復合屬性。比如地址可以包含郵編、街道、門牌號,它是一個復合屬性。
根據屬性的值的數量,屬性有單值屬性和多值屬性。比如一個人的姓名是一個單值屬性,而他的網名是多值屬性。多值屬性在ER圖里用雙線橢圓表示。
此外,還有導出屬性(派生屬性),它通過具有相互信賴的屬性推導出來,比如一個學生的平均成績。導出屬性在ER圖里用虛線橢圓表示。
注意屬性的值可以是空值。
存在依賴(Existence Dependency):如果實體x的存在依賴于實體y的存在,則稱x存在依賴于y。y稱作支配實體,而x稱作從屬實體(弱實體)。弱實體主鍵的一部分或全部從被依賴實體獲得。如果y被刪除,那么x也要被刪除。從屬實體的集合便稱為弱實體集。弱實體在ER圖里用雙線矩形表示。比如某單位的職工子女信息,如果職工不在該單位了,其子女信息也沒有意義了,所以職工子女信息是一個弱實體。
邏輯數據模型(Logical Data Model)貼近于計算機上的實現,是用戶從數據庫看到的模型,是具體DBMS所支持的數據模型。此模型既要面向用戶,又要面向系統,主要用于DBMS的實現。邏輯模型有層次模型、網狀模型和關系模型。
層次模型:用樹形結構表示實體類型及實體間聯系的數據模型,盛行于20世紀70年代。缺點是只能表示1:N的關系,且查詢和操作很復雜。
網狀模型:用有向圖表示實體類型及實體間聯系的數據模型,盛行于70年代至80年代中期。它的特點是記錄之間聯系通過指針實現,M:N也容易實現,查詢效率較高。缺點是數據結構復雜,編程復雜。
關系模型:用二維表格表示實體集;用關鍵碼而不是用指針導航數據。SQL語言是具有代表性的語言。
物理數據模型(Physical Data Model)面向于計算機物理表示,描述了數據在存儲介質上的組織結構,不僅和具體的DBMS有關,還與操作系統和硬件有關。每一種邏輯數據模型在實現時都有起對應的物理數據模型。DBMS為了保證其獨立性與可移植性,大部分物理數據模型的實現工作由系統自動完成,而設計者只設計索引、聚集等特殊結構。
ER模式的設計的過程為:設計局部ER模式、設計全局模式和全局ER模式的優化。
局部ER模式設計基于需求分析的結果,1、確定局部結構范圍;2、實體定義;3、聯系定義;4、屬性分配;5、查看是否還有待分析的局部結構,若有則跳到第2步,否則進入全局ER模式設計階段。
全局ER模式設計基于局部ER模式,1、確定公共實體類型;2、合并兩個局部的ER模式;3、檢查并消除沖突;4、重復第3步直到不再有沖突;5、檢查是否還有未合并的局部ER模式,若有則跳到第2步,否則便完成了ER模式設計。
全局ER模式的優化有:實體類型的合并(一般的可以把1:1聯系的兩個實體類型合并);冗余屬性的消除;冗余聯系的消除(通常利用規范化理論中的函數依賴的概念消除冗余聯系)。
在ER模式的設計過程中,常常要對ER模型進行種種變換。變換包括:分裂、合并和增加刪除。
實體的分裂有水平分裂和垂直分裂。水平分裂根據應用對象的不同,分成兩個具有相同屬性的實體,比如書店的書可以水平分裂成“有庫存”和“無庫存”兩個實體,這樣方便對兩種實體進行不同的操作。垂直分裂根據屬性的使用頻率,分成兩個屬性不同的實體,比如圖書有作者、版次、價格等屬性,分成包含常用的作者、版次屬性的圖書和包含不常用的價格屬性的圖書。垂直分裂的好處是可以減少每次存取的數據量。
聯系的分裂可以細化聯系,比如程序員和項目的聯系“參與”,可以分裂成“開發”和“維護”。
合并是分裂的逆過程。注意合并的聯系類型只能是定義在相同的實體類型上的。
ER模型向關系模型的轉換規則
實例類型的轉換:將每個實體類型轉換成一個關系模型,實體的屬性即為關系模型的屬性,實體的標識符即為關系模型的鍵。
二元聯系類型的轉換:
1:1聯系:在由實體轉換成的兩個關系模式之間選任一個加上一個屬性來表示另一個關系模式的鍵和聯系。也就是結果只有兩張表,其中一張表里會有外鍵表示聯系。
1:N聯系:在N端實體轉換成的關系模式里加上1端實體類型的鍵和聯系類型和屬性。最終的結果也是兩個表,N端的表有外鍵。
M:N聯系:將聯系類型轉換成關系模式,其屬性為兩端實體類型的鍵加上聯系類型的屬性,而鍵為兩端實體鍵的組合。最終的結果有三張表,其中一張表專門表示聯系,包含另兩個表的外鍵。
第三章 關系數據庫理論
關系模型是用二維表格表示實體,用鍵碼進行數據導航的數據模型。數據導航是指從已知數據查找未知數據的方法。在關系模型中,記錄稱為元組,為行(Row);字段稱為屬性,為列(Column)。
超鍵(Super Key)是可以唯一標識元組的屬性集。候選鍵(Candicate Key)是不含多余屬性的超鍵。主鍵(Primary Key)是用戶選做元組標識的候選鍵。外鍵(Foreign Key)是當模式R中的屬性K是其它模式的主鍵,那么K在R中稱為鍵。
舉個例子,屏幕上的點的信息表
| x坐標 | y坐標 | 顏色 | 大小 |
如果主鍵出現在別的表中,比如一個“射線”表
| x坐標 | y坐標 | 方向 |
關系是一個屬性集相同的元組的集合。由于是集合,因此:
1、關系中沒有重復的元組;
2、關系中的元組是無序的,即沒有行序;(理論上屬性集也是無序的,但使用時習慣考慮列的順序)。
每個屬性都是不可分解的整體,比如只能是整型、字符這種簡單類型,而不能是結構體這樣的復雜的類型。
根據元組的數目,關系可分為有限關系和無限關系。
關系模式有三類完整性規則:
1、實體完整性規則,即主鍵的值不能是空值;
2、參照完整性規則,即不允許(通過外鍵)引用不存在的實體;
3、用戶定義的完整性規則,比如屬性“性別”只能接受“男”和“女”作為合法值,其它的輸入都是非法的。
關于參照完整性,當在一個參照關系里作為刪除記錄時,有三種策略:
1、級聯刪除:將參照關系中所有外鍵值與被參照關系中要刪除的元組的主鍵值相同的元組一起刪除;
2、受限刪除:僅當參數關系中沒有外鍵與被參照關系中要刪除的元組主鍵值相同時才允許刪除,否則拒絕刪除操作;
3、置空值刪除:刪除被參照關系中的元組,并將參照關系中相應的外鍵值置空值。
而向參照關系插入元組時,有兩種策略:
1、受限插入:僅當被參照關系存在相應的元組,且其主鍵和要插入的元組的外鍵值相同時才允許插入,否則拒絕插入操作;
2、遞歸插入:首先在被參照關系里插入主鍵值等于參照關系里要插入的元組的外鍵值相同的元組,再在參照關系里插入元組。
關于實體完整性,主鍵的修改操作有兩種方法:一種是不允許修改主鍵;另一種是允許修改主鍵,但必須保證修改后的主鍵唯一且非空。當修改的主鍵是參照關系的外鍵時,可以使用三種策略:級聯修改、受限修改和置空值刪除。
關系代數的運算有多種。
五個基本操作:并(Union,∪)、差(set difference,?)、笛卡兒積(Cartesian product,×)、投影(Projection,Π)和選擇(Selection,σ);
四個組合操作:交(Intersection,∩)、θ連接(θ-Join,θ)、自然連接(Natural join,?)和除法(Division,÷);
七個擴充操作:改名(Rename,ρ)、廣義投影、賦值(←)、外連接(Outer joins,???)、外部并、半連接(Semijoin,? ?)、聚集操作(Aggregation)。
選擇運算:從關系中選擇滿足給定條件的元組。比如σA<5(R)在關系R中選擇屬性A的值小于5的元組。
投影運算:從關系中取出若干列組成新的關系,投影結果里要刪除重復的元組。比如ΠA,B(R)從關系R中取出屬性集(A、B)。
舉個例子,有學生信息表S1
| 學號 | 姓名 | 電話 |
| 1 | X | 123 |
| 2 | Y | 456 |
| 3 | Z | 789 |
并運算:合并兩個關系,即元組合并。這兩個關系必須是同構的,即屬性集應該相同。
例如有另一種學生信息表S2
| 學號 | 姓名 | 電話 |
| 3 | Z | 789 |
| 4 | M | 999 |
S1∪S2的結果為:
| 學號 | 姓名 | 電話 |
| 1 | X | 123 |
| 2 | Y | 456 |
| 3 | Z | 789 |
| 4 | M | 999 |
交運算:得到同時出現在兩個關系的元組集合。
例如,
S1∩S2的結果為:
| 學號 | 姓名 | 電話 |
| 3 | Z | 789 |
差運算:得到出現在一個關系而不在另一個關系的元組集合。
例如:
S1?S2的結果為:
| 學號 | 姓名 | 電話 |
| 1 | X | 123 |
| 2 | Y | 456 |
換句話說,(S1?S2)∩S2=?,而(S1?S2)∪S1=S1。
笛卡兒乘積運算:把一個關系中的每個元組和另一個關系的所有元組連接成新關系中的一個元組。新關系的元組數是兩個關系的元組數之積。
比如有一張選課表SC1
| 學號 | 課程 |
| 1 | 語文 |
| 2 | 數學 |
那么S1×SC1的結果為:
| 學號 | 姓名 | 電話 | 學號 | 成績 |
| 1 | X | 123 | 1 | 語文 |
| 1 | X | 123 | 2 | 數學 |
| 2 | Y | 456 | 1 | 語文 |
| 2 | Y | 456 | 2 | 數學 |
| 3 | Z | 789 | 1 | 語文 |
| 3 | Z | 789 | 2 | 數學 |
運算中的查詢優化:盡可能早地執行選擇操作和投影操作;避免直接做笛卡兒乘積,把笛卡兒乘積之前和之后的一連串操作和投影合并起來做。
除運算:它類似于(但不完全是)笛卡兒乘積的逆運算,被除關系的屬性集(M,N)真包含除關系的屬性集(N),得到的結果關系的屬性集為被除關系的屬性集與除關系的屬性集的差集(M),且結果關系是與除關系的笛卡兒乘積被包含于被除關系的最大關系。換句話說,若R1(M,N)÷?R2(N) = R3(M),則R3(M) × R2(N) ? R1(M,N),而在ΠM(R1)?R3里,沒有任何子集能足這樣的關系。
舉個例子,有選課表SC2
| 學號 | 課程 |
| 1 | 語文 |
| 2 | 數學 |
| 1 | 數學 |
| 課程 |
| 語文 |
| 數學 |
那么SC2?÷?C2的結果為:
| 學號 |
| 1 |
結果其實為選修了所有課程的學生號。
除運算的另一種形式表達為:r?÷?s =?ΠR-S(r)?-ΠR-S((ΠR-S(r)?× s)?-?ΠR-S,S(r))?(小寫r、s為關系名,而大寫R、S分別為r、s的屬性集)。
更名運算:ρx(E)可以返回關系表達式的結果,并重命名這個表達式為x。ρx(A1,A2,...,An)(E)同時將各屬性更名為A1、A2……,An。例如數學成績比王紅同學高的學生:ΠS.姓名(σR.成績<S.成績 ∧ R.課程=數學 ∧ S.課程=數學 ^ R.姓名=王紅(R ×ρS(R))。其實更名運算就是SQL里的as。
θ連接:從兩個關系的廣義笛卡兒積中選取給屬性間滿足一定條件的元組通常寫法為:
| R?S |
| A θ B |
A、B分別為R和S上可比的屬性列。θ為算術比較符,如果是等號則稱為等值連接。例如數學成績比王紅同學高的學生的另一種表示方式可以是:
| ΠS.姓名((σ課程=數學 ∧ 姓名=王紅(R)) | ? | σ課程=數學ρS(R) |
| R.成績 | < | S.成績 |
自然連接:從兩個關系的廣義笛卡兒積中選取在相同屬性列上取值相等的元組,并去掉重復的列。比如前面的S1表和SC1表的自然連接的結果為:
| 學號 | 姓名 | 電話 | 成績 |
| 1 | X | 123 | 語文 |
| 2 | Y | 456 | 數學 |
賦值運算:用于存儲臨時變量,比如r?÷?s的過程可寫成:
temp1??ΠR-S(r)
temp2?←ΠR-S(tmp1?× s) -?ΠR-S,S(r))
result?←temp1?-?temp2
廣義投影:在投影列表中使用算術表達式來對投影進行擴展:ΠF1, F2, ..., Fn(E),其中F1,F2,...Fn是算術表達式。比如:ΠA*5, B+3(R)。
外連接:為避免自然連接時因失配而發生的信息丟失,可以假定往參與連接的一方表中附加一個取值全為空值的行,它和參與連接的另一方表中的任何一個未匹配上的元組都能匹配,稱之為外連接。
外連接 = 自然連接 + 未匹配元組
外連接的形式有:左外連接、右外連接和全外連接。
左外連接 = 自然連接 + 左側表中未匹配元組
右外連接 = 自然連接 + 右側表中未匹配元組
全外連接 = 自然連接 + 兩側表中未匹配元組
考慮兩張表“學生借書信息”(R)
| 學號 | 書名 | 借出時間 |
| 1 | 數據庫 | 2012.1.2 |
| 5 | 設計模式 | 2012.3.6 |
| 8 | 操作系統 | 2012.4.8 |
和“學生會信息”(S):
| 學號 | 學生會 |
| 1 | 科技部 |
| 3 | 體育部 |
自然連接:R?S:
| 學號 | 書名 | 借出時間 | 學生會 |
| 1 | 數據庫 | 2012.1.2 | 科技部 |
左外連接:R?S
| 學號 | 書名 | 借出時間 | 學生會 |
| 1 | 數據庫 | 2012.1.2 | 科技部 |
| 5 | 設計模式 | 2012.3.6 | null |
| 8 | 操作系統 | 2012.4.8 | null |
右外連接:R?S
| 學號 | 書名 | 借出時間 | 學生會 |
| 1 | 數據庫 | 2012.1.2 | 科技部 |
| 3 | null | null | 體育部 |
全外連接:R?S
| 學號 | 書名 | 借出時間 | 學生會 |
| 1 | 數據庫 | 2012.1.2 | 科技部 |
| 3 | null | null | 體育部 |
| 5 | 設計模式 | 2012.3.6 | null |
| 8 | 操作系統 | 2012.4.8 | null |
半連接:類似于自然連接,但R???S?的連接的結果只是在?S?中有在公共屬性名字上相等的元組所有的R?中的元組,而R?S剛好相反。
還是以前面的“學生借書信息”和“學生會信息”為例:
R???S:
| 學號 | 書名 | 借出時間 |
| 1 | 數據庫 | 2012.1.2 |
R ? S:
| 學號 | 學生會 |
| 1 | 科技部 |
聚集函數:求一組值的統計信息,返回單一值。使用聚集的集合可以是多重集,即一個值可以重復出現多次。如果想去除重復值,可以用連接符“-”將“distinct”附加在聚集函數 名后,如sum-distinct。
聚集函數包括:
sum:求和。例如求001號學生的總成績:sumscore(σs#=001(SC))
avg:求平均數。
count:計數。
max:求最大值。
min:求最小值。
聚集函數可以使用分組,將一個元組集合分為若干個組,在每個分組上使用聚集函數。它的形式是:屬性下標G聚集函數屬性下標(關系)。例如
“學號G avg分數(成績表)”得到每個學生的平均成績。
分組運算G的一般形式是:G1,G2,...,GnGF1(A1),F2(A2),...,Fm(Am)(E)。在關系表達式E里,所有在G1,G2,...,Gn上相等的元組分成一組,分別在屬性A1上執行F1,屬性A2上執行F2,…,屬性Am上執行Fm。
第四章 結構化查詢語言
SQL可以分為兩類:數據操作語言(Data Manipulation Language,DML)和數據定義語言(Data Definition Language,DDL)。
DML由查詢和更新命令組成:
- SELECT:從數據庫中取出數據。
- UPDATE:更新數據庫的數據。
- DELETE:從數據庫中刪除數據。
- INSERT INTO:向數據庫插入新數據。
DDL創建和刪除數據庫、創建和刪除表、定義索引(關鍵字)、指定表之間的聯系、定義表之間的約束。SQL里最重要的DDL的語句有:
- CREATE DATABASE:創建一個新的數據庫
- ALTER DATABASE:修改一個數據庫。
- CREATE TABLE?:創建一張新的表。
- ALTER TABLE?:修改一張表。
- DROP TABLE?:刪除一張表。
- CREATE INDEX?:創建一個索引。
- DROP INDEX?:刪除一個索引。
用SELECT進行查詢時,可以會有重復的記錄。使用DISTINCT語句可以消除重復數據。比如:select distinct name from persons。使用WHERE可以指定查詢的目標,比如:select * from persons where age >= 18。
| = | Equal |
| <> | Not equal |
| > | Greater than |
| < | Less than |
| >= | Greater than or equal |
| <= | Less than or equal |
| BETWEEN | Between an inclusive range |
| LIKE | Search for a pattern |
| IN | To specify multiple possible values for a column |
Note:?In some versions of SQL the <> operator may be written as !=
IN的語法是
FROM table_name
WHERE column_name IN (value1,value2,...)
BETWEEN的語法是:
SELECT column_name(s)FROM table_name
WHERE column_name
BETWEEN value1 AND value2
在對字符串比較時,需要用單引號包圍字符串常量(多數據數據庫系統也接受雙引號),數值不應該使用綽號。
LIKE比較時可以使用的通配符有:
| % | A substitute for zero or more characters |
| _ | A substitute for exactly one character |
| [charlist] | Any single character in charlist |
| [^charlist] or [!charlist] | Any single character not in charlist |
在進行條件判斷時,可以使用AND和OR來連接邏輯表達式。
可以使用ORDER BY對查詢的結果進行排序,它的語法為
SELECT column_name(s)
FROM table_name
ORDER BY column_name(s) ASC|DESC
在mysql里,可以使用LIMIT子句來定義查詢結果的最大數量。?比如:select * from persons order by age limit 1。會看到年紀最小的人。在SQL Server里等價的語句是
FROM table_name
注意limit和top都不是SQL標準。
INSERT用來插入數據,語法為:
VALUES (value1, value2, value3,...)
The second form specifies both the column names and the values to be inserted:
INSERT INTO table_name (column1, column2, column3,...)VALUES (value1, value2, value3,...)
UPDATE更新數據,語法為:
UPDATE table_nameSET column1=value, column2=value2,...
WHERE some_column=some_value
DELETE刪除表示的行,語法為:
DELETE FROM table_nameWHERE some_column=some_value
SELECT column_name(s)
FROM table_name
AS alias_name
SQL里的連接
- JOIN:自然連接;
- LEFT JOIN:左外連接;
- RIGHT JOIN:右外連接;
- FULL JOIN:全外連接。
INNER JOIN?語法
SELECT column_name(s)FROM table_name1
INNER JOIN table_name2
ON table_name1.column_name=table_name2.column_name
LEFT JOIN?語法
SELECT column_name(s)FROM table_name1
LEFT JOIN table_name2
ON table_name1.column_name=table_name2.column_name
RIGHT JOIN 語法
SELECT column_name(s)FROM table_name1
RIGHT JOIN table_name2
ON table_name1.column_name=table_name2.column_name
FULL JOIN 語法
SELECT column_name(s)FROM table_name1
FULL JOIN table_name2
ON table_name1.column_name=table_name2.column_name
UNION?求并集,語法為:
SELECT column_name(s) FROM table_name1UNION
SELECT column_name(s) FROM table_name2
Note:?The UNION operator selects only distinct values by default. To allow duplicate values, use UNION ALL.
UNION ALL保留重復的記錄:
SELECT column_name(s) FROM table_name1UNION ALL
SELECT column_name(s) FROM table_name2
SELECT INTO 可以把查詢結果寫入一張表里
We can select all columns into the new table:
SELECT *INTO new_table_name [IN externaldatabase]
FROM old_tablename
Or we can select only the columns we want into the new table:
SELECT column_name(s)INTO new_table_name [IN externaldatabase]
FROM old_tablename
CREATE DATABASE 語法
CREATE DATABASE database_nameCREATE TABLE 語法
CREATE TABLE table_name(
column_name1 data_type,
column_name2 data_type,
column_name3 data_type,
....
)
SQL約束
約束限定可以插入表的數據的類型。它可以在表創建(CREATE TABLE)時指定,也可以在表創建手(用ALTER TABLE)指定。常用的約束有:
- NOT NULL
- UNIQUE
- PRIMARY KEY
- FOREIGN KEY
- CHECK
- DEFAULT
NOT NULL約束強制某一列不接受NULL值。比如:
CREATE TABLE Persons(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
UNIQUE約束保證某列沒有重復記錄。在mysql中可以在創建表時有兩種方法指定:
CREATE TABLE Persons(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (P_Id)
)
或: CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
)
注意第二種方式可以同時指定多列,只有在這些列上都相等的記錄才視為重復。
在表創建后加入UNIQUE約束的方法是:
ALTER TABLE PersonsADD UNIQUE (P_Id)
或
ADD CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
注意:如果該列中已經有重復的記錄,那么加入約束會失敗
刪除UNIQUE約束:
ALTER TABLE PersonsDROP INDEX uc_PersonID
創建PRIMARY KEY約束:
CREATE TABLE Persons(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (P_Id)
)
修改表來加入PRIMARY KEY約束:
ALTER TABLE PersonsADD PRIMARY KEY (P_Id)
或
ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
刪除PRIMARY KEY約束:
ALTER TABLE PersonsDROP PRIMARY KEY
創建外鍵?FOREIGN KEY:
CREATE TABLE Orders(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
)
修改表以創建FOREIGN KEY?:
ALTER TABLE OrdersADD FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id) 或
ALTER TABLE Orders
ADD CONSTRAINT fk_PerOrders
FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
刪除FOREIGN KEY約束:
ALTER TABLE OrdersDROP FOREIGN KEY fk_PerOrders
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CHECK (P_Id>0)
)
或
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
)
修改表以創建CHECK約束:
ALTER TABLE PersonsADD CHECK (P_Id>0)
或
ADD CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
刪除CHECK約束:
ALTER TABLE PersonsDROP CONSTRAINT chk_Person
或
DROP CHECK chk_Person
創建DEFAULT約束:
My SQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'Sandnes'
)
修改表以創建DEFAULT約束:
ALTER TABLE PersonsALTER City SET DEFAULT 'SANDNES'
或
ALTER COLUMN City SET DEFAULT 'SANDNES'
刪除DEFAULT約束:
ALTER TABLE PersonsALTER City DROP DEFAULT
創建AUTO INCREMENT約束,它只能作用在主鍵上:
CREATE TABLE Persons(
P_Id int NOT NULL?AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (P_Id)
)
我們可以設置自增的起始值:
ALTER TABLE Persons AUTO_INCREMENT=100
Indexes
索引用來提高數據查找的效率,用戶看不到索引的存在。注意:使用索引會使更新表的速度變慢,因為數據更新的同時還要更新索引。
在表上創建一個允許重復值的索引:
CREATE INDEX index_nameON table_name (column_name)
在表上創建唯一的索引:
CREATE UNIQUE INDEX index_nameON table_name (column_name)
刪除INDEX:
ALTER TABLE table_name DROP INDEX index_name
一個表上的約束可以通過SHOW INDEX FROMtbl_name來查看。mysql上可以通過修改一個列來增加約束:
ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column'; ALTER TABLE t1 CHANGE b b BIGINT NOT NULL; 但是要刪除約束只能使用前面所述的drop ...的方式。
DROP TABLE?刪除一張表:
DROP TABLE table_name
DROP DATABASE?刪除一個數據庫:
DROP DATABASE database_name
TRUNCATE TABLE可以刪除一張表的所有數據而不刪除該表:
TRUNCATE TABLE table_name
ALTER TABLE 可以修改一張表:
增加一列:ALTER TABLE table_name
ADD column_name datatype
刪除一列:
DROP COLUMN column_name
修改一列:
ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column';ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
視圖是基于一個SQL語句的結果集的一張虛擬表。視圖的優點有:
提供了邏輯數據獨立性。當數據的邏輯結構發生改變時,原有的應用程序不用修改。
簡化了用戶觀點。用戶只需用到數據庫中的一部分,視圖適應了用戶需要。
數據的安全保護功能。針對不同用戶定義不同視圖。
創建視圖:
SELECT column_name(s)
FROM table_name
WHERE condition
更新視圖: CREATE OR REPLACE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
刪除視圖 :
DROP VIEW view_name
MySQL的日期函數:
| NOW() | Returns the current date and time |
| CURDATE() | Returns the current date |
| CURTIME() | Returns the current time |
| DATE() | Extracts the date part of a date or date/time expression |
| EXTRACT() | Returns a single part of a date/time |
| DATE_ADD() | Adds a specified time interval to a date |
| DATE_SUB() | Subtracts a specified time interval from a date |
| DATEDIFF() | Returns the number of days between two dates |
| DATE_FORMAT() | Displays date/time data in different formats |
MySQL日期數據類型
- DATE - format YYYY-MM-DD
- DATETIME - format: YYYY-MM-DD HH:MM:SS
- TIMESTAMP - format: YYYY-MM-DD HH:MM:SS
- YEAR - format YYYY or YY
WHERE Address IS NULL
IS NOT NULL?操作符判斷非空值:
WHERE Address IS NOT NULL
MySQL沒有ISNULL函數,所以它使用IFNULL:
FROM Products
或COALESCE()函數:
SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0))FROM Products
MySQL數據類型
MySQL有三種主要類型:text, number和Date/Time。
Text types:
| CHAR(size) | Holds a fixed length string (can contain letters, numbers, and special characters). The fixed size is specified in parenthesis. Can store up to 255 characters |
| VARCHAR(size) | Holds a variable length string (can contain letters, numbers, and special characters). The maximum size is specified in parenthesis. Can store up to 255 characters.Note:?If you put a greater value than 255 it will be converted to a TEXT type |
| TINYTEXT | Holds a string with a maximum length of 255 characters |
| TEXT | Holds a string with a maximum length of 65,535 characters |
| BLOB | For BLOBs (Binary Large OBjects). Holds up to 65,535 bytes of data |
| MEDIUMTEXT | Holds a string with a maximum length of 16,777,215 characters |
| MEDIUMBLOB | For BLOBs (Binary Large OBjects). Holds up to 16,777,215 bytes of data |
| LONGTEXT | Holds a string with a maximum length of 4,294,967,295 characters |
| LONGBLOB | For BLOBs (Binary Large OBjects). Holds up to 4,294,967,295 bytes of data |
| ENUM(x,y,z,etc.) | Let you enter a list of possible values. You can list up to 65535 values in an ENUM list. If a value is inserted that is not in the list, a blank value will be inserted. Note:?The values are sorted in the order you enter them. You enter the possible values in this format:ENUM('X','Y','Z') |
| SET | Similar to ENUM except that SET may contain up to 64 list items and can store more than one choice |
Number types:
| TINYINT(size) | -128 to 127 normal. 0 to 255 UNSIGNED*. The maximum number of digits may be specified in parenthesis |
| SMALLINT(size) | -32768 to 32767 normal. 0 to 65535 UNSIGNED*. The maximum number of digits may be specified in parenthesis |
| MEDIUMINT(size) | -8388608 to 8388607 normal. 0 to 16777215 UNSIGNED*. The maximum number of digits may be specified in parenthesis |
| INT(size) | -2147483648 to 2147483647 normal. 0 to 4294967295 UNSIGNED*. The maximum number of digits may be specified in parenthesis |
| BIGINT(size) | -9223372036854775808 to 9223372036854775807 normal. 0 to 18446744073709551615 UNSIGNED*. The maximum number of digits may be specified in parenthesis |
| FLOAT(size,d) | A small number with a floating decimal point. The maximum number of digits may be specified in the size parameter. The maximum number of digits to the right of the decimal point is specified in the d parameter |
| DOUBLE(size,d) | A large number with a floating decimal point. The maximum number of digits may be specified in the size parameter. The maximum number of digits to the right of the decimal point is specified in the d parameter |
| DECIMAL(size,d) | A DOUBLE stored as a string , allowing for a fixed decimal point. The maximum number of digits may be specified in the size parameter. The maximum number of digits to the right of the decimal point is specified in the d parameter |
*The integer types have an extra option called UNSIGNED. Normally, the integer goes from an negative to positive value. Adding the UNSIGNED attribute will move that range up so it starts at zero instead of a negative number.
Date types:
| DATE() | A date. Format: YYYY-MM-DD Note:?The supported range is from '1000-01-01' to '9999-12-31' |
| DATETIME() | *A date and time combination. Format: YYYY-MM-DD HH:MM:SS Note:?The supported range is from '1000-01-01 00:00:00' to '9999-12-31 23:59:59' |
| TIMESTAMP() | *A timestamp. TIMESTAMP values are stored as the number of seconds since the Unix epoch ('1970-01-01 00:00:00' UTC). Format: YYYY-MM-DD HH:MM:SS Note:?The supported range is from '1970-01-01 00:00:01' UTC to '2038-01-09 03:14:07' UTC |
| TIME() | A time. Format: HH:MM:SS Note:?The supported range is from '-838:59:59' to '838:59:59' |
| YEAR() | A year in two-digit or four-digit format. Note:?Values allowed in four-digit format: 1901 to 2155. Values allowed in two-digit format: 70 to 69, representing years from 1970 to 2069 |
SQL聚集函數計算某列的各值,返回單一值。
有用的集體函數有:
- AVG() -平均數
- COUNT() -計數
- FIRST() -第一個值
- LAST() -最后一個值
- MAX() -最大值
- MIN() -最小值
- SUM() -求和
這些函數會計算重復值,可以使用DISTINCT來消除重復,比如:select sum(distinct?age) from persons。
結果也可以用AS來起別名,比如select sum(age) as MySum from persons。
在MySql里沒有first和last,所以
等價于:
SELECT OrderPrice FROM Orders ORDER BY O_Id LIMIT 1
SELECT LAST(OrderPrice) AS LastOrderPrice FROM Orders
等價于:
GROUP BY可以根據記錄在某列上的值把表的記錄分組,然后分別計算各組的聚集函數的值。它也能指定多個列比如:
SELECT Customer,OrderDate,SUM(OrderPrice) FROM OrdersGROUP BY?Customer,OrderDate
HAVING可以在查詢時使用一個聚集函數來指定條件,它之前必須可以有group by修飾:
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value
Having與WHERE的區別是:
where決定哪些元組被選擇參加運算,作用于關系中的元組;
Having決定哪些分組符合要求,作用于分組;
聚集函數的條件關系必須用Having,Where不應該出現聚集函數。
SQL標量函數基于輸入值返回單個值。有用的標量函數有:
- UCASE() -轉換成大寫。
- LCASE() - 轉換成小寫。
- MID() - 抽取子字符串。
- LEN() - 得到字符串的長度。
- ROUND() - 舍取一個小數。
- NOW() - 返回當前日期和時間。
- FORMAT() - 格式化顯示。
SQL UCASE() 語法
SELECT UCASE(column_name) FROM table_name
SQL MID() 語法
SELECT MID(column_name,start[,length]) FROM table_nameSQL ROUND() 語法
SELECT ROUND(column_name,decimals) FROM table_nameSQL FORMAT() 語法
SELECT FORMAT(column_name,format) FROM table_name| column_name | Required. The field to be formatted. |
| format | Required. Specifies the format. |
參考:http://www.w3schools.com/sql
第五章 數據庫設計
軟件工程與軟件生命周期
軟件生存期是指從軟件的規劃、研制、實現、測試、投入運行后的維護,直到它被新的軟件所取代而停止使用的整個歷程。
數據庫工程與數據庫生存期
數據庫應用系統從規劃、設計、實現、測試、運行中的維護到最后被新的系統取代而停止使用的整個期間,稱為數據庫生存期。它包括規劃、需求分析、概念設計、邏輯設計、物理設計、實現、運行和維護。
數據庫設計的輸入輸出
輸入:總體信息需求、處理需求、DBMS的特征、硬件和OS特征。
輸出:完整的數據庫結構、基于數據庫結構和處理需求的應用程序設計原則。
數據庫設計的階段劃分
規劃階段:系統調查、可行性分析、確定數據庫系統的總目標和制定項目開發計劃。
需求分析階段:分析用戶活動,產生業務流程圖;確定系統范圍,產生系統范圍圖;分析用戶活動設計的數據,產生數據流圖;分析系統數據,產生數據字典。
概念設計階段:進行數據抽象,設計局部概念模式;將局部概念模式綜合成全局概念模式。
邏輯設計階段:從之前得到的概念模式出發,1、導出初始DBMS模式說明;2、子模式設計和應用程序設計草圖;3、模式評價;4,如果處理結束,則進入物理設計階段,否則進入下一步;5、檢查模式是否需要修正,如果需要則修正模式,并回到第2步,否則回到前面的階段。
物理設計階段:存儲記錄結構設計;確定數據存放位置;存取方法的設計;完整性和安全性考慮;程序設計。
數據庫實現:定義數據庫結構;數據裝載(大型應用和小型應用);編制和調試應用程序;數據庫試運行。
數據庫的運行與維護:數據庫的轉儲和恢復;數據安全性、完整性控制;數據庫性能的監督,分析和改進;數據庫的重組織和重構造。
之前所述的總體信息需求在需求分析和概念設計中被使用;處理需求在需要分析、邏輯設計、物理設計階段中都有使用;DBMS特征在邏輯設計和物理設計階段中被使用;硬件和OS特征只在物理設計階段被使用。
第六章 關系數據庫的規范化理論
問題的提出
設有關系模式R(姓名,電話,參與的俱樂部,俱樂部的活動),候選碼為(姓名,參與的俱樂部)。
| 姓名 | 電話 | 參與的俱樂部 | 俱樂部的活動 |
| A | 123 | 乒乓club | 打乒乓球 |
| A | 123 | 登山club | 爬山 |
| B | 456 | 乒乓club | 打乒乓球 |
| B | 456 | 英語club | 學習英語 |
| C | 789 | 登山club | 爬山 |
| C | 789 | 英語club | 學習英語 |
注意到上面的模式有什么問題?
1、數據冗余:一個人參與幾個俱樂部,那么他的電話會重復幾次;同樣,一個俱樂部被幾個人參加,它的活動就會重復幾次。
2、修改異常:一旦一個人的手機號變化,那么對應于他參與的每個俱樂部的各行里的電話都需要修改,如果有遺漏,那么會造成數據不一致;俱樂部的活動也是如此。
3、插入異常:如果一個新人到來,還未參加任何俱樂部,那么他的信息和電話就無法插入到這張表里,因為參與的俱樂部是主屬性,不能為空。
4、刪除異常:如果某人暫時退出了所有的俱樂部,那么必須把所有的元組都刪去,這樣這個人的姓名和電話信息也不存在了。
問題的解決方式是把關系模式R分解成三個模式:
| 姓名 | 電話 |
| A | 123 |
| B | 456 |
| C | 789 |
| 俱樂部 | 活動 |
| 乒乓club | 打乒乓球 |
| 英語club | 學習英語 |
| 登山club | 爬山 |
| 姓名 | 參與的俱樂部 |
| A | 乒乓club |
| A | 登山club |
| B | 乒乓club |
| B | 英語club |
| C | 登山club |
| C | 英語club |
函數依賴(FD,Functional Dependency)
實際上關系模式的更新異常是由屬性間的數據依賴引起的,數據依賴指數據之間存在著某種內在的聯系,如姓名和電話之間,每一個人都有一個確定的電話,姓名的一個取值可以確定唯一的地址。
函數依賴的概念為:設有關系模式R(U),X和Y是屬性集U的子集,函數依賴是形為X→Y的一個命題,只要有r是R的當前關系,對r中的任意兩個元組t和s,都有t[X] = s[X]蘊涵t[Y] = s[Y],那么稱函數依賴X→Y在關系模式R(U)中成立。比如前面的U是(姓名,電話,參與的俱樂部,俱樂部的活動),子集X為(姓名),子集Y為(電話)。
函數依賴的文字化定義:設R(U)是屬性集U上的關系模式,X、Y是U的子集,若對于R(U)的任意一個可能的關系r,R中不可能存在兩個元組在X的屬性值上相等,而在Y上的屬性值不等,則稱“X函數確定Y”,或“Y函數依賴于X”,記作X→Y。例如姓名→電話。
FD的推理規則有:
基本規則:
1、自反性:Y?X???X?→Y
2、增廣性:XZ?→YZ
3、傳遞性:X?→Y, Y?→Z???X?→Z
擴展規則:
4、合并性:{X?→Y, X?→Z}???X?→YZ
5、分解性:{X?→Y, Z ? Y}???X?→Z
6、偽傳遞性:{X?→Y, WY?→Z}???WX?→Z
7、復合性:{X?→Y, W?→Z}???WX?→YZ
函數依賴的性質有:
1、若X→Y,但X ? Y,則稱X→Y是非平凡的函數依賴,一般不特殊指明的情況下,我們總是討論非平凡函數依賴。
2、若X→Y,則稱X是決定因素。
3、若Y不函數依賴于X,則記作X?Y
4、若X→Y,Y→X,則稱X與Y一一對應,記為X?Y。
在R(U)中,如果X→Y,并且對于X的任意一個真子集X',都有X'?Y,則稱Y完全函數依賴于X,或Y對X完全函數依賴,記作X-f->Y,否則稱Y對X部分函數依賴,X-p->Y。
在關系模式R(U)中,如果X→Y,(X ? Y),Y→Z,則稱Z對X傳遞函數依賴。
設K為R<u,f>中的屬性或屬性組,若K-f->u,則K為R的候選碼,若候選碼多于一個,則選其中一個作為主碼。特殊情況:所有屬性構成碼,稱為全碼。包含在任何一個候選碼中的屬性,叫主屬性(Prime Attribute),不包含在任何碼中的屬性為非主屬性,或非碼屬性。
關系模式R中屬性或屬性組X并非R的主碼,但它是另一個關系模式的主碼,則稱X是R的外碼(Foreign Key)。關系間是通過主碼和外碼進行聯系的。
規范化理論
1971年起E.F.Codd提出了規范化理論。該理論按屬性間的依賴情況(如函數依賴)規范關系模式。按規范化的程度不同分為第一范式1NF(Normal Form)、2NF、3NF、BCNF及4NF,逐步消除更新異常問題。
若R屬于第幾范式,一般記為R∈XNF,一個低一級范式的關系模式,通過模式分解總可以將它分解為若干個高一級范式的關系模式的結合,這種過程就叫規范化。
設有關系模式R(U),屬性集為U,R1、……、Rk都是U的子集,并且有R1∪R2∪……∪Rk=U。關系模式R1,……,Rk的集合用ρ={R1,……,Rk}。用ρ代替R的過程為關系模式的分解。
1NF指每一個分量都是不可分的,這是最基本的規范化。即關系的所有屬性都只能是預定義的簡單變量,如整型,而不能是結構體。
2NF的定義為:如果R∈1NF,且每個非主屬性完全函數依賴于碼,則R∈2NF。如本章最開始提出的問題,在屬性性(姓名,電話,參與的俱樂部,俱樂部的活動)里,候選碼為(姓名,參與的俱樂部),即姓名和參與的俱樂部是主屬性,但是“電話”部分函數依賴于“姓名”,并沒有完全函數依賴于碼;“俱樂部的活動”同樣也部分函數依賴于“俱樂部”。它便是由于違反了2NF,才造成了更新異常。而表的拆分便是關系模式的分解。
3NF的定義:關系模式R<U,F>中若不存在這樣的碼X,屬性組Y及非主屬性Z(Z?Y),便利X→Y,Y→Z成立,則稱R∈3NF。
比如關系
| 員工 | 所在分公司 | 分公司總裁 |
其中“員工”是主碼,員工→所在分公司,所在分公司→分公司總裁。所以它違反了3NF。它造成的問題有修改異常:員工換了分公司的話,總裁屬性也必須修改。遺漏會造成數據不一致。我們可以把它模式分解為:
| 員工 | 所在分公司 |
| 分公司 | 總裁 |
2NF、3NF有一個缺陷:它們只限制了主碼對非主屬性的部分函數依賴或傳遞函數依賴,但并沒有對主屬性進行限制。
比如
| 學號 | 姓名 | 課程名 |
假定姓名沒有重名的,那么(學號,課程名)和(姓名,課程名)都可以是候選鍵,也就是說三個屬性都是主屬性。如果我們選取(學號,課程名)作為主碼,有(學號,姓名)→學號,學號→姓名的傳遞依賴,也可以理解為部分依賴,但是因為姓名是主屬性,所以這個關第符合2NF、3NF。然而,它有之前討論過的冗余和更新異常的問題。
BCNF(Boyce Codd Normal Form)是由Boyce和Codd提出的,比3NF又進一步,通常認為BCNF是修正的第三范式,有時也稱為3NF。它的定義為:如果關系模式R是1NF,且每個屬性(包括主屬性)都不傳遞依賴于R的候選鍵,那么稱R是BCNF范式。若R∈BCNF,則R∈3NF。
范式是衡量關系模式好壞的標準,它與數據依賴有著直接的聯系。1NF是關系模式的基礎(對象模式違背了1NF),2NF已經稱為歷史,3NF和BCNF是最為常見的范式。
第七章 數據存儲
物理存儲媒介的分類
高速緩沖區:現今的AMD和Intel的CPU都在芯片內部集成了數據高速緩存和指令高速緩存,通稱了L1高速緩存;比L1更大的L2高速緩存曾放在CPU外部的主板或CPU接口上,現在已經成為CPU內部的標準部件了;高端家用機或工作站甚至配備了L3緩存器。高速緩存使用靜態隨機存取存儲器(StaticRandomAccessMemory,?SRAM)技術,比主存的DRAM技術快。
主存儲區:使用動態隨機存取(Dynamic Random Access Memory,DRAM)技術,性價比很高,擴展性也不錯。DRAM里面所儲存的數據需要周期性地更新,所以比SRAM較慢。最近生產的(2010年后)計算機主要使用的主存是DDR 3 SDRAM(第三代雙倍資料率同步動態隨機存取內存,Double-Data-Rate Three Synchronous Dynamic Random Access Memory)。
快擦寫存儲器:一種EEPROM芯片,EEPROM,或寫作E2PROM,全稱電子抹除式可復寫只讀內存?(Electrically-Erasable Programmable Read-Only Memory),是一種可以通過電子方式多次復寫的半導體存儲設備。相比EPROM(Erasable Programmable Read Only Memory,可擦除可編程式只讀內存),EEPROM不需要用紫外線照射,也不需取下,就可以用特定的電壓,來抹除芯片上的信息,以便寫入新的數據。EEPROM被廣泛用于需要經常擦除的BIOS芯片,以及快閃存儲器(Flash Memory,簡稱閃存),并逐步替代部分有斷電保留需要的RAM芯片,甚至取代部份的硬盤功能(固態硬盤Solid State Disk、Solid State Drive,簡稱SSD)。
磁盤存儲器:利用磁記錄技術在涂有磁記錄介質的旋轉圓盤上進行數據存儲的輔助存儲器。具有存儲容量大、數據傳輸率高、存儲數據可長期保存等特點。
光存儲器:由光盤驅動器和光盤片組成的光盤驅動系統,光存儲技術是一種通過光學的方法讀寫數據的一種技術,它的工作原理是改變存儲單元的某種性質的反射率,反射光極化方向,利用這種性質的改變來寫入存儲二進制數據.在讀取數據時,光檢測器檢測出光強和極化方向等的變化,從而讀出存儲在光盤上的數據.由于高能量激光束可以聚焦成約0.8μm的光束,并且激光的對準精度高,因此它比硬盤等其他存儲技術具有較高的存儲容量.
磁帶:一種用于記錄聲音、圖像、數字或其他信號的載有磁層的帶狀材料,是產量最大和用途最廣的一種磁記錄材料。作為數字信息的存貯具有容量大、價格低的優點。主要大量用于計算機的外存貯器。目前僅在專業設備上使用(比如車床控制機)。
數據存儲文件的組織結構
堆文件:Heap File。插入的記錄被添加到文件的末尾,因此文件是無序的。記錄被刪除時,會在文件中間留下空白行,所以堆文件需要周期性地壓縮來恢復空間。
順序文件:Sequential File。記錄以查找鍵的升序或降序的順序存儲。文件在載入到內存里時,可以以隨機方式讀取數組,比如可用二分查找法來優化查找時間。但把新記錄寫入到文件時,必須以順序方式。
散列文件:Hash File。記錄存儲的地址(塊號)是記錄的某個屬性值通過散列函數求得的值。
聚集文件:Cluster File。“聚集(Clustering)”的意義是為了訪問的效率把相關的數據存儲在一起。多個數據庫和多上表被合并(join)被稱為聚集(cluster)。共享同一個聚集關鍵字的表被存儲在一起,在相同或相鄰的數據塊里。這樣可以提升表在聚集關鍵字上進行的聚集操作的效率。
第八章 索引機制
索引的概念:在數據文件中,根據記錄建立的一種數據結構,以次線性時間查找(sublinear time lookup)來加快查詢速度。索引也用來監管數據庫約束,比如unique、exclusion、primary key和foreign key。
索引的架構(Index architecture)
非簇集索引(Non-Clustered):數據以任意序表示,但索引指明了它的邏輯序(logical ordering)。數據行無視被索引的列的值而遍布在表中,但非簇集索引樹包含排好序的索引關鍵字,并在葉子級包含記錄的指針(頁結構引擎(page-organized engines)里的頁和數據頁里的行號;文件結構引擎(file-organized engines)里的行偏移量)。
在非簇集索引里,數據存儲的順序和索引不同。索引通常在join、where、和order by語句里使用的非主鍵列上創建。在一個數據庫表上,可以創建多個非簇集索引。
簇集索引(Clustered):數據塊以特定的順序聚集來匹配索引,導致行數據順序存儲。因此,一張表只能創建一個簇集索引。如果文件記錄以非碼字段排序,那么這個字段稱為簇集字段(cluster field)。
有些數據庫把簇集索引和記錄分開存儲在不同文件里,而其它一些則把它們存儲在同一文件的不同數據塊里。簇集索引里包含有序的記錄,每個記錄包含兩人個字段。第一個字段和數據的簇集字段有相同的數據類型;第二個字段是一個指針。
當數據以和簇集索引相同或相反的順序訪問,或選擇一個范圍里的數據時,簇集索引可以大幅提升訪問速度。
索引的類型(Types of indexes)
位圖索引(Bitmap index):一種特殊的索引,把它的大塊數據存儲在位數組(bit array)里,也就是位圖里。多數查詢都通過位邏輯操作來完成。如果索引的值不重復或只重復較少的次數時,那么最普遍使用的索引,比如b+tree,是最高效的。相反,位圖索引被設計用在變量值頻繁重復的情況下。比如只有“男”和“女”的性別屬性。
稠密索引(Dense index):數據文件里的每個記錄所對應的“關鍵字-指針”對所組成的文件。也就是說,數據文件里每個記錄都有索引。在有重復關鍵字的簇集索引里,稠密索引指向該關鍵字的第一條記錄。
稀疏索引(Sparse index):或非稠密索引(nondense index)。數據文件里的每個塊都有相應的“關鍵字-塊”對。在有重復關鍵字的簇集索引里,塊指針指向每個塊的最小的搜索鍵(lowest search key)。
逆索引(Reverse index):在把關鍵字插入到索引之前,把關鍵字翻轉。比如:值12345在索引里成為54321。它對于索引諸如序號(sequence number,單調增加的值)的值非常有用,特別是在大容量的事務處理系統(Transaction processing system)上,因為它們可以減少索引塊的競爭。
逆索引使用b-tree結構實現。
主索引和輔索引
主索引(Primary Key)建立在有序文件中的排序碼字段上。輔索引(Secondary Key)指定在文件的任何非排序字段上。同一個文件只能有一個主存取方式,但是可以有多個輔助索引,從而有多個索引字段。當輔索引建立在碼上時,該碼字段被稱為輔碼(Secondary Key)。
索引文件的組織:線性索引、樹形索引和散列索引。
第九章 并發控制和故障恢復
事務、并發控制的概念
事務(Transaction)是構成單一邏輯工作單元的操作集合。
在多用戶在線共享系統中,許多事務可能同時對同一數據進行操作,稱為并發操作。并發可能導致的問題有:丟失更新問題、讀脹數據問題、錯誤求和問題、和不可重復讀問題等等。
并發控制負責協調并發事務的執行,保證數據庫的完整性,同時避免用戶得到不正確的數據。
事務的基本屬性
原子性(Atomicity):一個事務對數據庫的所有操作,是一個不可分割的工作單元。這些操作要么全部執行,要么什么也不做。
一致性(Consistency):一個事務獨立執行的結果,應保持數據庫的一致性,即數據不會因事務的執行而遭到破壞。
隔離性(Isolation):在多個事務并發執行時,系統應保證與這些事務先后獨立執行的結果一樣。
持久性(Durability):一個事務一旦完成全部操作后,他對數據庫的所有更新應永久地反映在數據庫中。
這些屬性的首字母縮寫為ACID。其中原子性是最主要的根本目標;其它三個是輔助的屬性。
第十章 數據庫完整性機制
數據庫完整性的概念
與關系數據庫的完整性不同,數據庫完整性表示數據的正確性(accurate)、有效性(valid)和相容性(consistent),防止錯誤的數據進入數據庫。
正確性指數據的合法性;
有效性指數據是否屬于所定義的有效范圍;
相容性指表示同一事實的兩個數據應相同。
在對數據庫提交修改前,必須要滿足所應用的完整性約束(Integrity constraints)和數據驗證(Data validation)。
完整性除了在第三章所述的實體完整性(Entity Integrity)、參照完整性(Referential Integrity)、和用戶定義完整性(User Defined Integrity),還有域完整性(Domain Integrity):數據必須為預定義的數據類型,同時屬性值的限制:比如取值范圍,沒有提供值時的默認值,以及是否可以為空等。
完整性子系統
DBMS中執行完整性檢查的子系統稱為“完整性子系統”。它檢測事務的執行,并測試是否違反完整性的規則。若有違反完整性規則,則采取適當的操作。
完整性規則集
完整性規則集是由DBA或應用程序員事先向完整性子系統提供的有關數據約束的一組規則。它由以下部分組成:
1、什么時候使用規則進行檢查(稱為規則的觸發條件);
2、要檢查什么樣的錯誤(稱為約束條件或謂詞);
3、如果查出錯誤,應該怎么辦(稱為“ELSE子句”,即違反時要做的動作)。
SQL完整性約束分類
域約束:在域定義中定義的一種約束。域約束與在特定域中定義的任何列有關。
斷言:在斷言定義中定義一種約束。斷言可以與一個或多個表進行關聯。
斷言僅僅是一種可以用于多個表的CHECK約束,因此必須在表定義之外獨立的創建斷言。
與表相關的約束:它是在表定義中定義的一種約束。該約束可以被定義為列定義的一部分,或者定義為表定義中的一個元素。在表級別定義的約束可以應用于一個或多個列。
列約束:NOT NULL,UNIQUE PRIMARY KEY,FOREIGN KEY,CHECK
表約束:UNIQUE PRIMARY KEY,FOREIGN KEY,CHECK
第十一章 數據庫安全機制
數據庫安全性機制的概念
數據庫的安全是指保護數據庫,防止不合法的使用,導致數據的泄密、更改或破壞。
安全性的級別
環境級:計算機系統的機房和設備應加以保護,防止有人進行物理破壞。
職員級:工作人員應清正廉潔,正確授予用戶訪問數據庫的權限。
OS級:應防止未經過授權的用戶從OS處著手訪問數據庫。
網絡級:由于大多數DBS都允許用戶通過網絡進行遠程訪問,因此網絡軟件內部的安全性是很重要的。
DBS級:DBS的職責是檢查用戶的身份是否合法以及使用數據庫的權限是否正確。
授權子系統
自主訪問控制(DAC)
自主訪問控制機制允許對象的屬主來制定針對該對象的保護策略。通常DAC通過授權列表(或訪問控制列表)來限定哪些主體針對哪些客體可以執行什么操作。如此將可以非常靈活地對策略進行調整。由于其易用性與可擴展性,自主訪問控制機制經常被用于商業系統。
六種權限:SELECT、INSERT、DELETE、UPDATE、REFERENCES、和USAGE。
賦予權限:GRANT <權限表> ON <數據庫元素> TO <用戶名表> [WITH GRANT OPTION]
收回權限:REVOKE <權限表> ON <數據庫元素> FROM <用戶名表> [RESTRICT | CASCADE]
強制訪問控制(MAC)
用來保護系統確定的對象,對此對象用戶不能進行更改。也就是說,系統獨立于用戶行為強制執行訪問控制,用戶不能改變他們的安全級別或對象的安全屬性。這樣的訪問控制規則通常對數據和用戶按照安全等級劃分標簽,訪問控制機制通過比較安全標簽來確定的授予還是拒絕用戶對資源的訪問。強制訪問控制進行了很強的等級劃分,所以經常用于軍事用途。
視圖機制
用來對無權用戶屏蔽數據。數據安全,邏輯數據獨立性和操作簡便性。
數據加密
常用的數據庫加密技術有:庫外加密、庫內加密、和硬件加密。
總結
- 上一篇: 5G学习-3GPP协议入门
- 下一篇: 数据库的基本知识