什么是范式:范式, 英文名稱是 Normal Form,它是英國人 E.F.Codd(關(guān)系數(shù)據(jù)庫的老祖宗)在上個世紀70年代提出關(guān)系數(shù)據(jù)庫模型后總結(jié)出來的,范式是關(guān)系數(shù)據(jù)庫理論的基礎(chǔ),也是我們在設(shè)計數(shù)據(jù)庫結(jié)構(gòu)過程中所要遵循的規(guī)則和指導方法,簡言之就是,數(shù)據(jù)庫設(shè)計對數(shù)據(jù)的存儲性能,還有開發(fā)人員對數(shù)據(jù)的操作都有莫大的關(guān)系。所以建立科學的,規(guī)范的的數(shù)據(jù)庫是需要滿足一些規(guī)范的來優(yōu)化數(shù)據(jù)數(shù)據(jù)存儲方式。在關(guān)系型數(shù)據(jù)庫中這些規(guī)范就可以稱為范式。
什么是三大范式:
第一范式:當關(guān)系模式R的所有屬性都不能在分解為更基本的數(shù)據(jù)單位時,稱R是滿足第一范式的,簡記為1NF。滿足第一范式是關(guān)系模式規(guī)范化的最低要
求,否則,將有很多基本操作在這樣的關(guān)系模式中實現(xiàn)不了。
第二范式:如果關(guān)系模式R滿足第一范式,并且R得所有非主屬性都完全依賴于R的每一個候選關(guān)鍵屬性,稱R滿足第二范式,簡記為2NF。
第三范式:設(shè)R是一個滿足第一范式條件的關(guān)系模式,X是R的任意屬性集,如果X非傳遞依賴于R的任意一個候選關(guān)鍵字,稱R滿足第三范式,簡記為3NF.
注:關(guān)系實質(zhì)上是一張二維表,其中每一行是一個元組,每一列是一個屬性
第一范式
1、每一列屬性都是不可再分的屬性值,確保每一列的原子性
2、兩列的屬性相近或相似或一樣,盡量合并屬性一樣的列,確保不產(chǎn)生冗余數(shù)據(jù)。
如果需求知道那個省那個市并按其分類,那么顯然第一個表格是不容易滿足需求的,也不符合第一范式。
顯然第一個表結(jié)構(gòu)不但不能滿足足夠多物品的要求,還會在物品少時產(chǎn)生冗余。也是不符合第一范式的。
第一范式是最基本的范式。如果數(shù)據(jù)庫表中的所有字段值都是不可分解的原子值,就說明該數(shù)據(jù)庫表滿足了第一范式。
第一范式的合理遵循需要根據(jù)系統(tǒng)的實際需求來定。比如某些數(shù)據(jù)庫系統(tǒng)中需要用到“地址”這個屬性,本來直接將“地址”屬性設(shè)計成一個數(shù)據(jù)庫表的字段就行。但是如果系統(tǒng)經(jīng)常會訪問“地址”屬性中的“城市”部分,那么就非要將“地址”這個屬性重新拆分為省份、城市、詳細地址等多個部分進行存儲,這樣在對地址中某一部分操作的時候?qū)⒎浅7奖?。這樣設(shè)計才算滿足了數(shù)據(jù)庫的第一范式,如下表所示。
上表所示的用戶信息遵循了第一范式的要求,這樣在對用戶使用城市進行分類的時候就非常方便,也提高了數(shù)據(jù)庫的性能。
第二范式
每一行的數(shù)據(jù)只能與其中一列相關(guān),即一行數(shù)據(jù)只做一件事。只要數(shù)據(jù)列中出現(xiàn)數(shù)據(jù)重復,就要把表拆分開來。
一個人同時訂幾個房間,就會出來一個訂單號多條數(shù)據(jù),這樣子聯(lián)系人都是重復的,就會造成數(shù)據(jù)冗余。我們應該把他拆開來。
這樣便實現(xiàn)啦一條數(shù)據(jù)做一件事,不摻雜復雜的關(guān)系邏輯。同時對表數(shù)據(jù)的更新維護也更易操作。
第二范式在第一范式的基礎(chǔ)之上更進一層。第二范式需要確保數(shù)據(jù)庫表中的每一列都和主鍵相關(guān),而不能只與主鍵的某一部分相關(guān)(主要針對聯(lián)合主鍵而言)。也就是說在一個數(shù)據(jù)庫表中,一個表中只能保存一種數(shù)據(jù),不可以把多種數(shù)據(jù)保存在同一張數(shù)據(jù)庫表中。
比如要設(shè)計一個訂單信息表,因為訂單中可能會有多種商品,所以要將訂單編號和商品編號作為數(shù)據(jù)庫表的聯(lián)合主鍵,如下表所示。
訂單信息表
這樣就產(chǎn)生一個問題:這個表中是以訂單編號和商品編號作為聯(lián)合主鍵。這樣在該表中商品名稱、單位、商品價格等信息不與該表的主鍵相關(guān),而僅僅是與商品編號相關(guān)。所以在這里違反了第二范式的設(shè)計原則。
而如果把這個訂單信息表進行拆分,把商品信息分離到另一個表中,把訂單項目表也分離到另一個表中,就非常完美了。如下所示。
這樣設(shè)計,在很大程度上減小了數(shù)據(jù)庫的冗余。如果要獲取訂單的商品信息,使用商品編號到商品信息表中查詢即可。
第三范式
數(shù)據(jù)不能存在傳遞關(guān)系,即沒個屬性都跟主鍵有直接關(guān)系而不是間接關(guān)系。像:a-->b-->c 屬性之間含有這樣的關(guān)系,是不符合第三范式的。
比如Student表(學號,姓名,年齡,性別,所在院校,院校地址,院校電話)
這樣一個表結(jié)構(gòu),就存在上述關(guān)系。 學號--> 所在院校 --> (院校地址,院校電話)
這樣的表結(jié)構(gòu),我們應該拆開來,如下。
(學號,姓名,年齡,性別,所在院校)--(所在院校,院校地址,院校電話)
第三范式需要確保數(shù)據(jù)表中的每一列數(shù)據(jù)都和主鍵直接相關(guān),而不能間接相關(guān)。
比如在設(shè)計一個訂單數(shù)據(jù)表的時候,可以將客戶編號作為一個外鍵和訂單表建立相應的關(guān)系。而不可以在訂單表中添加關(guān)于客戶其它信息(比如姓名、所屬公司等)的字段。如下面這兩個表所示的設(shè)計就是一個滿足第三范式的數(shù)據(jù)庫表。
這樣在查詢訂單信息的時候,就可以使用客戶編號來引用客戶信息表中的記錄,也不必在訂單信息表中多次輸入客戶信息的內(nèi)容,減小了數(shù)據(jù)冗余。
最后:
三大范式只是一般設(shè)計數(shù)據(jù)庫的基本理念,可以建立冗余較小、結(jié)構(gòu)合理的數(shù)據(jù)庫。如果有特殊情況,當然要特殊對待,數(shù)據(jù)庫設(shè)計最重要的是看需求跟性能,需求>性能>表結(jié)構(gòu)。所以不能一味的去追求范式建立數(shù)據(jù)庫。
注意事項:
1.第二范式與第三范式的本質(zhì)區(qū)別:在于有沒有分出兩張表。
第二范式是說一張表中包含了多種不同實體的屬性,那么必須要分成多張表,第三范式是要求已經(jīng)分好了多張表的話,一張表中只能有另一張標的ID,而不能有其他任何信息,(其他任何信息,一律用主鍵在另一張表中查詢)。
2.必須先滿足第一范式才能滿足第二范式,必須同時滿足第一第二范式才能滿足第三范式。
二:數(shù)據(jù)庫中的五大約束:
數(shù)據(jù)庫中的五大約束包括:
1.主鍵約束(Primay Key Coustraint) 唯一性,非空性;
2.唯一約束 (Unique Counstraint)唯一性,可以空,但只能有一個;
3.默認約束 (Default Counstraint) 該數(shù)據(jù)的默認值;
4.外鍵約束 (Foreign Key Counstraint) 需要建立兩表間的關(guān)系;
5.非空約束(Not Null Counstraint):設(shè)置非空約束,該字段不能為空。
詳細介紹:
(1)[外鍵約束 (Foreign Key Counstraint) ]
1.設(shè)置外鍵的注意事項:
?、伲褐挥蠭NNODB的數(shù)據(jù)庫引擎支持外鍵,修改my.ini文件設(shè)置default-storage-engine=INNODB;
?、冢和怄I與參照列的數(shù)據(jù)類型必須相同。(數(shù)值型要求長度和無符號都相同,字符串要求類型相同,長度可以不同);
?、郏涸O(shè)置外鍵的字段必須要有索引,如果沒有索引,設(shè)置外鍵時會自動生成一個索引;
2.設(shè)置外鍵的語法:
[CONSTRAINT 外鍵名] FOREIGN KEY(外鍵字段) REFERENCES 參照表(參照字段);
[ON DELETE SET NULL ON UPDATE CASCADE] -- 設(shè)置操作完整。
3、外鍵約束的參照操作:
當對參照表的參照字段進行刪除或更新時,外鍵表中的外鍵如何應對。
參照操作可選值:
RESTRICT: 拒絕對參照字段的刪除或修改(默認);
NO ACTION:與RESTRICT相同,但這個指令只在MySql生效;
CASCADE: 刪除或更新參照表的參照字段時,外鍵表的記錄同步刪除或更新;
SET NULL: 刪除刪除或更新參照表的參照字段時,外鍵表的外鍵設(shè)為NULL (此時外鍵不能設(shè)置為NOT NULL)。
(2)[主鍵約束](Primay Key Coustraint)
1.主鍵的注意事項:主鍵默認非空,默認唯一性約束,只有主鍵可以設(shè)置自動增長(主鍵不一定自增,自增一定是主鍵)。
2.設(shè)置主鍵的方式:
?、伲涸诙x列時設(shè)置:id INT UNSIGNED PRIMARY KEY。
②:在列定義完成后設(shè)置:PRIMARY KEY(id)。
其他約束沒有特殊要求因此不做解釋。
如對本文有疑問,請?zhí)峤坏浇涣髡搲瑥V大熱心網(wǎng)友會為你解答?。?點擊進入論壇