文章目錄
- 一、基本概念
- 1、屬性
- 2、元組
- 3、關系
- 4、超鍵
- 5、候選鍵
- 6、主鍵
- 7、主屬性
- 8、外鍵
- 9、函數依賴
- 完全依賴
- 二、數據庫范式
- 1、第一范式(1NF)
- 2、第二范式(2NF)
- 3、第三范式(3NF)
- 4、巴斯-科德范式(BCNF)
- 5、第四范式(4NF)
- 6、第五范式(5NF)
- 三、反范式
- 四、總結
一、基本概念
我們通過下面這個學生表來深入理解下,假設姓名沒有重名的
學生表:姓名,性別,年齡,是否成年,身份證號碼,手機號碼,學號,班級,學生所在班級中的座位號,班主任
1、屬性
屬性就是字段,我們表中的每一列
2、元組
元組就是表中的每行數據(即數據庫表中的每條記錄),在二維表里,元組也稱為行。
3、關系
關系(Relation)是指一個表(Table),它由行(Rows)和列(Columns)組成。
4、超鍵
超鍵,又叫超碼,是能夠唯一標識關系中的每個元組的一個或多個屬性的集合,也就是在關系中能唯一標識記錄的屬性集。
超鍵可以包含多個屬性,但不一定是最小的,超鍵+任何屬性=超鍵
超鍵的分類:
- 單屬性:表中的某個屬性
- 組合:由多個屬性組成
- 唯一性約束超鍵:通過在屬性上添加唯一性約束,使其成為超鍵
例如,有一個學生表(學號,姓名,性別,年齡,身份證,班級),那么{學號}、{身份證}、{學號, 姓名}、{學號, 性別}等都是超鍵,{姓名},{姓名,性別}不是超鍵。
5、候選鍵
候選鍵,又叫候選碼,是最小的超鍵,不含有多余屬性的超鍵,也就是一個屬性可以表示超鍵的話,就沒必要使用多個屬性。
在一個關系中,可能存在多個候選鍵
特點:
- 唯一性:候選鍵的值在關系中是唯一的,沒有重復的記錄。
- 最小性:候選鍵是最小的屬性集合,即不能再刪除任何一個屬性而保持唯一性。
例如,還是以學生表(學號,姓名,性別,年齡,身份證,班級)來說,{學號}、{身份證}都是候選鍵,因為它唯一標識每個學生;{學號, 性別}不是候選鍵,因為它包含了多余屬性。
6、主鍵
主鍵,又叫主碼,是從候選鍵中選擇的一個鍵,用于唯一標識關系中的每個元組。
主鍵必須是唯一且非空的。在關系中,只能有一個主鍵。
例如,在學生表中,{學號}、{身份證}都可以作為主鍵。
注:還是要根據場景,來定主鍵,比如身份證,一般在實際生產中,我們不用它當主鍵。
7、主屬性
主屬性,是指在主鍵中的屬性,它們是用來唯一標識每個元組的關鍵屬性。
如果主鍵包含多個屬性,那么這多個屬性都是主屬性。
例如,在學生表中,{學號}是主鍵,因此它也是主屬性。
8、外鍵
外鍵,又叫外碼,是指其它表的主鍵。
例如,在學生表中,{班級}是外鍵,因為它是班級表的主鍵
9、函數依賴
一個屬性的值(或屬性集合的值)對于另一個屬性的值(或屬性集合的值)具有決定性影響,即給定一個屬性(或屬性集合)的值,可以唯一確定另一個屬性(或屬性集合)的值
例如,如果屬性A的值決定了屬性B的值,可以表示為 A -> B。這意味著在給定A的值的情況下,可以唯一確定B的值。
完全依賴
如果一個屬性(或屬性集合)對于另一個屬性(或屬性集合)的值具有完全依賴,那么沒有任何冗余的屬性可以從該依賴中刪除,否則將無法唯一確定被依賴的屬性(或屬性集合)的值。
例如,假設有一個關系模式R(A, B, C),其中屬性A和屬性B的組合決定了屬性C的值。如果刪除屬性A或屬性B中的任何一個,都無法唯一確定屬性C的值,那么我們可以說屬性C對于屬性A和屬性B具有完全依賴。
二、數據庫范式
主要有第一范式、第二范式、第三范式、巴斯-科德范式,第四范式和第五范式,前面是后續范式的基礎,級別越高,數據庫越標準。
1、第一范式(1NF)
1NF=First Normal Form
強調屬性都是原子的,不可再拆分
例如,學生表(學號,姓名,班級,學生所在班級中的座位號,班主任,性別,年齡,是否成年,身份證號碼),這個表設計符不符合第一范式?
這種得看業務場景了,如果需要展示xx姓同學,比如黃同學,李同學,歐陽同學這種,是不是就不符合,因為姓可能有多個字,比如歐陽索隆,歐陽修,你怎么知道姓歐還是歐陽,這種根本無法拆分,所以,需要把姓和名拆開存,不然不好展示,代碼邏輯也比較復雜,所以這里的姓名還可以再拆分,就不符合第一范式了。
2、第二范式(2NF)
非主鍵屬性完全依賴于主鍵,消除部分依賴
。
假設(A,B)是主鍵,完全依賴指的是(A,B) ->(C),部分依賴指的是(A)->(C)。
還是以學生表(學號,姓名,班級,學生所在班級中的座位號,班主任,性別,年齡,是否成年,身份證號碼)為例,這個表設計符不符合第二范式?
{班級,學生所在班級中的座位號}是主鍵,但{班主任}由班級決定,沒有完全依賴于主鍵,不符合第二范式,而且會有性能影響,這里數據冗余了,可能導致數據不一致,如果班主任有變更,很多學生記錄都要同步修改,不然就出現了數據不一致。
解決方案:拆表,班主任字段拆出去
學生表(學號,姓名,班級,學生所在班級中的座位號,性別,年齡,是否成年,身份證號碼)
班級表(班級,班主任)
3、第三范式(3NF)
非主鍵屬性不傳遞依賴于主鍵,直接依賴于主鍵,消除傳遞依賴
假設A是主鍵,存在A->B->C,那么說C傳遞依賴于A。
例如,前面滿足第二范式的表結構如下,這個表設計符不符合第三范式?
學生表(學號,姓名,班級,學生所在班級中的座位號,性別,年齡,是否成年,身份證號碼)
班級表(班級,班主任)
年齡,是否成年,身份證號碼,性別,都是非主鍵列,“年齡”和“性別”都可以由“身份證號碼”推出,“是否成年”可以由“年齡”推出,所以不符合第三范式
解決方案:拆表,把年齡,是否成年,身份證號碼拆出去
學生表(學號,姓名,班級,學生所在班級中的座位號,身份證號碼)
班級表(班級,班主任)
身份證號碼關系表(身份證號碼,年齡,性別)
年齡關系表(年齡,是否成年)
上面這種場景,在實際環境中,需要維護多一些表或者Java代碼進行判斷,都有性能消耗,代碼的話,每次查詢的時候,代碼都要計算1次,那么我們可以采取物化視圖,插入年齡的時候,直接計算好,提升性能,具體實現可以參考數據庫對象介紹與實踐:視圖、函數、存儲過程、觸發器和物化視圖
4、巴斯-科德范式(BCNF)
對第三范式的優化,在它基礎上,消除對主鍵子集的依賴而得到的,即非主鍵屬性完全依賴于候選鍵
。
學生表(學號,姓名,班級,學生所在班級中的座位號,身份證號碼)
班級表(班級,班主任)
身份證號碼關系表(身份證號碼,年齡,性別)
年齡關系表(年齡,是否成年)
這個設計符不符合巴斯-科德范式?
學生所在班級中的座位號完全依賴于{學號,班級},而不依賴于學號,所以符合
5、第四范式(4NF)
要求消除非平凡多值依賴。
假設有一個關系表格包含以下列:學生ID、課程ID、學生成績1、學生成績2。如果每個學生ID和課程ID的組合可以決定多個學生成績的值,而不是只有一個固定的學生成績值,那么就存在一個非平凡多值依賴。
6、第五范式(5NF)
要求消除非平凡函數依賴。
假設有一個關系表格包含以下列:學生ID、學生姓名、學生年齡。如果每個學生ID都唯一確定一個學生姓名,那么學生ID對學生姓名存在一個非平凡函數依賴。因為在現實生活中,學生ID并不直接決定學生姓名,而是通過其他信息或邏輯來確定。
三、反范式
反范式(Denormalization)是一種數據庫設計技術,旨在提高數據庫的性能和查詢效率,但可能會犧牲一部分數據的一致性和完整性。
在范式化的數據庫設計中,數據被分解為多個表,以減少數據冗余和提高數據的一致性。然而,范式化的數據庫結構可能導致在進行復雜查詢時需要進行多個表的連接操作,從而影響查詢性能。
反范式化通過將分解的表重新合并或添加冗余數據,以減少表之間的連接操作,從而提高查詢性能。這樣可以簡化查詢的復雜性,減少查詢的執行時間。
導致的問題:
- 增加存儲空間,數據冗余字段
- 增大更新風險,更新時,需要確保所有相關的冗余數據都得到正確的更新,以保持數據的一致性
四、總結
在實際工作中,一般遵守1NF、2NF、3NF即可,但一般用反范式,可以顯著提高性能優勢,我們需要自己權衡下,根據具體的應用場景和性能需求來決定使用啥范式。
經驗之談:
- 設計的時候,腦子里要有范式,用于指導設計
- 遵守范式,然后根據業務,再做反范式