引用自 https://blog.csdn.net/u013164931/article/details/79692402
基礎知識
實體:現實世界中客觀存在並可以被區別的事物。比如“一個學生”、“一本書”、“一門課”等等。值得強調的是這里所說的“事物”不僅僅是看得見摸得着的“東西”,它也可以是虛擬的,比如說“老師與學校的關系”。
屬性:教科書上解釋為:“實體所具有的某一特性”,由此可見,屬性一開始是個邏輯概念,比如說,“性別”是“人”的一個屬性。在關系數據庫中,屬性又是個物理概念,屬性可以看作是“表的一列”。
元組:表中的一行就是一個元組。
分量:元組的某個屬性值。在一個關系數據庫中,它是一個操作原子,即關系數據庫在做任何操作的時候,屬性是“不可分的”。否則就不是關系數據庫了。
碼:表中可以唯一確定一個元組的某個屬性(或者屬性組),如果這樣的碼有不止一個,那么大家都叫候選碼,我們從候選碼中挑一個出來做老大,它就叫主碼。
全碼:如果一個碼包含了所有的屬性,這個碼就是全碼。
主屬性:一個屬性只要在任何一個候選碼中出現過,這個屬性就是主屬性。
非主屬性:與上面相反,沒有在任何候選碼中出現過,這個屬性就是非主屬性。
外碼:一個屬性(或屬性組),它不是碼,但是它別的表的碼,它就是外碼。
第一范式
第一范式列不能再分。
第二范式
第二范式建立在第一范式的基礎上,非主屬性完全依賴於碼。
簡單說:消除部分依賴。
(什么是碼?) 表中可以唯一確定一個元組的某個屬性(或者屬性組),如果這樣的碼有不止一個,那么大家都叫候選碼,我們從候選碼中挑一個出來做老大,它就叫主碼。注意碼可以包含多個屬性。
要理解第二第三范式需要理解完全函數依賴、部分函數依賴、傳遞函數依賴。
完全函數依賴
定義:設X,Y是關系R的兩個屬性集合,X’是X的真子集,存在X→Y,但對每一個X’都有X’!→Y,則稱Y完全函數依賴於X。
比如通過學號->姓名
部分函數依賴
定義:設X,Y是關系R的兩個屬性集合,存在X→Y,若X’是X的真子集,存在X’→Y,則稱Y部分函數依賴於X。
需要借用知乎劉慰教師的例子用一下,自己也理解了很長時間。
碼用(學號+課程),為什么要加課程呢?因為不同課程成績是通過學號查不出來的。
不過用(學號+課程)當作碼是不是有些問題?
(學號+課程)->姓名,但是學號->姓名
(學號+課程)->系名,但是學號->系名
(學號+課程)->系主任,但是學號->系主任
這個就是部分依賴,說實話我看定義一臉懵逼。
要是上面那張表符合第二范式。需要將表拆分為兩張表。
一張是 學號、課程、分數表
另外一張是 學號、姓名、系名、系主任表
傳遞函數依賴
設X,Y,Z是關系R中互不相同的屬性集合,存在X→Y(Y !→X),Y→Z,則稱Z傳遞函數依賴於X。
https://blog.csdn.net/rl529014/article/details/48391465
采用這位大佬的例子
在關系R(學號 ,宿舍, 費用)中,(學號)->(宿舍),宿舍!=學號,(宿舍)->(費用),費用!=宿舍,所以符合傳遞函數的要求
第三范式
滿足第二范式的條件下不存在傳遞函數依賴。
要滿足第三范式,在分成兩張表的時候第二張表還是有問題?
學號->系名,系名->系主任 傳遞依賴。
需要將系名和系主任另外新建一張表。
總結:
第一范式:簡單說 列不能再分
第二范式:簡單說 建立在第一范式基礎上,消除部分依賴
第三范式:簡單說 建立在第二范式基礎上,消除傳遞依賴。
碼:表中可以唯一確定一個元組的某個屬性(或者屬性組),如果這樣的碼有不止一個,那么大家都叫候選碼,我們從候選碼中挑一個出來做老大,它就叫主碼。
主屬性:一個屬性只要在任何一個候選碼中出現過,這個屬性就是主屬性。
非主屬性:與上面相反,沒有在任何候選碼中出現過,這個屬性就是非主屬性。
BCNF范式
https://www.2cto.com/database/201404/290140.html
BCNF是3NF的改進形式
一個滿足BCNF的關系模式的條件:
1.所有非主屬性對每一個碼都是完全函數依賴。
2.所有的主屬性對每一個不包含它的碼,也是完全函數依賴。
3.沒有任何屬性完全函數依賴於非碼的任何一組屬性。
如上表
(倉庫名,管理員)->(物品名,數量)
(管理員,物品名)->(倉庫名,數量)
但是(倉庫名)->(管理員) 不滿足第二條
所以需要改成兩種表:
第一張:倉庫名,管理員
第二張:倉庫名,物品名,數量