理論性的東西,往往容易把人人都看得懂的東西寫(xiě)成連鬼都看不懂,近似于主任醫(yī)生開(kāi)的藥方。從前學(xué)范式的時(shí)候,把書(shū)中得概念翻來(lái)覆去看,看得痛心疾首深?lèi)和唇^,再加上老師深切誤導(dǎo),最后一塌糊涂。借助網(wǎng)絡(luò)資源,自己寫(xiě)了一篇,自己是看懂了,希望對(duì)大家也有所幫助,有錯(cuò)誤幫忙指正。
數(shù)據(jù)庫(kù)范式(Normal forms):是用于規(guī)范關(guān)系型數(shù)據(jù)庫(kù)設(shè)計(jì),以減少謬誤發(fā)生的一種準(zhǔn)則。
1NF(first normal form):
Table faithfully represents a relation and has no repeating groups.
數(shù)據(jù)庫(kù)表必須如實(shí)地展現(xiàn)“關(guān)系”,并且不允許有“重復(fù)組”出現(xiàn)。
這樣的概念真是令人痛心疾首,我們只好再搬出1NF的的作者之一Chris Date的解釋?zhuān)?/span>
1. There's no top-to-bottom ordering to the rows.
(任意兩行沒(méi)有特定的順序關(guān)系。不存在一個(gè)特定的理由要某一行必須在另一行之前。)
2. There's no left-to-right ordering to the columns.
(任意兩列沒(méi)有特定的順序關(guān)系。)
3. There are no duplicate rows.
(不允許存在重復(fù)的行。如果一張表沒(méi)有Unique Key,事實(shí)上它是違反1NF的。)
4. Every row-and-column intersection contains exactly one value from the applicable domain (and nothing else).
(不允許出現(xiàn)空值Null,這一點(diǎn)不同作者是有爭(zhēng)議的。事實(shí)上我們常常違背這點(diǎn)。)
5. All columns are regular [i.e. rows have no hidden components such as row IDs, object IDs, or hidden timestamps].
(不允許存在隱藏字段。不知道Oracle的Rowid屬不屬于這個(gè)?)
有人從第四點(diǎn)的“one value”大肆挖掘,于是我們就見(jiàn)到了書(shū)上這樣的定義:“如果一個(gè)關(guān)系模式R的所有屬性都是原子的,即不可再分的基本數(shù)據(jù)項(xiàng),則RÎ1NF”。
這一點(diǎn)被認(rèn)為是1NF的核心,“關(guān)系模式R”↔“表”,“屬性” ↔ “列”,下面是一種與1NF不一致的情況,通常這是一類(lèi)很明顯的設(shè)計(jì)缺陷:
ID
|
Artist
|
FavoriteColor
|
……
|
1
|
Babyface
|
Blue,Yellow
|
……
|
2
|
Sting
|
Green
|
……
|
對(duì)上例我們不能把它拆分成FavoriteColor1、FavoriteColor2……因?yàn)槭紫任覀儾荒艽_定該拆分成幾列;其次FavoriteColor1與FavoriteColor2在結(jié)構(gòu)、含意方面都是相同的,這實(shí)際上也是一類(lèi)“repeating group”;同時(shí)這種設(shè)計(jì)會(huì)導(dǎo)致某些查詢困難,比如“有哪些藝人喜歡黃色?”
解決方案是將表拆分成兩個(gè):
ID
|
Artist
|
……
|
1
|
Babyface
|
……
|
2
|
Sting
|
……
|
ID
|
FavoriteColor
|
1
|
Blue
|
1
|
Yellow
|
2
|
Green
|
總結(jié):
對(duì)1NF最核心的 “原子性”,違反此規(guī)范的可能性:接近于0%。不過(guò),網(wǎng)上很多帖子說(shuō)在關(guān)系型數(shù)據(jù)庫(kù)中根本不可能違背1NF,我認(rèn)為這是不對(duì)的。
2NF(second normal form):
No non-prime attribute in the table is functionally dependent on a part (proper subset) of a candidate key.
不存在非主屬性對(duì)任一候選鍵的部分函數(shù)依賴。
如果解釋完下面幾個(gè)概念,這個(gè)定義就可以讀懂了:
Superkey:超級(jí)鍵(L),如果屬性或?qū)傩越M合能唯一標(biāo)識(shí)一條記錄,則它是一個(gè)Superkey。
Candidate key:候選鍵,當(dāng)Superkey只包含一個(gè)屬性時(shí),則它是一個(gè)候選鍵;當(dāng)Superkey包含一組屬性時(shí),僅當(dāng)這一組屬性不包含另一Superkey時(shí),它是一個(gè)候選鍵。換句話說(shuō),候選鍵是“純凈的”、最小化的Superkey。
Non-prime attribute:非主屬性,未在任何候選鍵中出現(xiàn)的屬性,即為非主屬性。
舉例來(lái)說(shuō),對(duì)表{First_name,Last_name,Address},假定全名不重復(fù),則:
Superkey:
{First_name,Last_name}
{First_name,Last_name,Address}
Candidate key:
{First_name,Last_name}
Non-prime attribute:
Address
淺白版:“2NF針對(duì)的是復(fù)合候選鍵(即鍵包含的字段個(gè)數(shù)>1)的情況,非主屬性不能只依賴于復(fù)合候選鍵中的一部分字段。”顯然,如果是非復(fù)合候選鍵,如果它符合1NF,那么它一定符合2NF。
假設(shè)有這樣一張涉及藝人與唱片公司的關(guān)系表:
Artist
藝人
|
Company
唱片公司
|
DurationYears
簽約總年數(shù)
|
CompAddr
公司住址
|
Babyface
|
Solar
|
4
|
Indiana
|
Babyface
|
Laface
|
2
|
Indiana
|
|
|
|
|
顯然,{Artist,Company}為可以作為一個(gè)候選鍵,DurationYears在這沒(méi)有問(wèn)題,但CompAddr是違反2NF的,它只依賴于候選鍵的一部分(依賴于Company),這是違反2NF的,為了消除這種情況,我們可以:
Artist
藝人
|
CompID
唱片公司
|
DurationYears
簽約總年數(shù)
|
Babyface
|
1
|
4
|
Babyface
|
2
|
2
|
ID
|
Company
唱片公司
|
CompAddr
公司住址
|
1
|
Solar
|
Indiana
|
2
|
Laface
|
Indiana
|
總結(jié):
對(duì)于2NF,如果關(guān)系中的候選鍵只包含一個(gè)屬性,可以直接略過(guò)。
在考慮2NF的過(guò)程中,不要把幾個(gè)無(wú)關(guān)的實(shí)體的屬性雜揉放在一個(gè)關(guān)系中,比如Artist是一個(gè)實(shí)體、Company是一個(gè)實(shí)體,它們可以有一系列的關(guān)聯(lián)表(也是實(shí)體),但在關(guān)聯(lián)表中盡量不要引入前兩個(gè)實(shí)體的無(wú)關(guān)屬性。
3NF(Third normal form)
Every non-prime attribute is non-transitively dependent on every key of the table.
不存在非主屬性對(duì)任一鍵(候選鍵)的傳遞依賴。
傳遞依賴,你可以顧名思義,這里就不再引入定義了,舉個(gè)例子,有下面一張表:
Tournament
賽事
|
Year
年份
|
Winner
冠軍
|
Winner Date of Birth
冠軍生日
|
Indiana Invitational
|
1998
|
Al Fredrickson
|
21 July 1975
|
Cleveland Open
|
1999
|
Bob Albertson
|
28 September 1968
|
Des Moines Masters
|
1999
|
Al Fredrickson
|
21 July 1975
|
Indiana Invitational
|
1999
|
Chip Masterson
|
14 March 1977
|
這里的候選鍵為{Tournament,Year},顯然有這樣的決定關(guān)系:
{Tournament,Year}→Winner
{Tournament,Year}→Winner→Winner Date of Birth
其中第二條就屬于違反3NF的情況,因?yàn)?/span>Winner Date of Birth依賴于Winner而不是直接依賴于候選鍵。這種情況下,可以將Winner,Winner Date of Birth單獨(dú)作為一張表,這里不贅述。
總結(jié):
我覺(jué)得大多數(shù)人憑借直觀感覺(jué),就可使設(shè)計(jì)的關(guān)系符合3NF,所以這些理論,你只需要姑且讀之。
BCNF(Boyce-Codd normal form)(Boyce與Codd是該范式的兩名作者。)
Every non-trivial functional dependency in the table is a dependency on a superkey.
表中的任何非平凡函數(shù)依賴,都必須是對(duì)superkey的依賴。
non-trivial functional dependency:非平凡函數(shù)依賴,如果存在一個(gè)決定關(guān)系x→y,且y并非x的子集,則叫著y非平凡函數(shù)依賴于x。
BCNF與3NF的最大區(qū)別是它并不僅針對(duì)非主屬性(non-prime attribute)來(lái)說(shuō),它發(fā)生的時(shí)候常常是表中根本不存在非主屬性,以至于它不可能違反2NF或3NF。而BCNF的出現(xiàn)就是為了擴(kuò)大“打擊面”。
于是BCNF的主旨是:補(bǔ)充對(duì)發(fā)生在主屬性(prime attribute)身上的函數(shù)依賴的約束,因?yàn)閷?duì)于非主屬性的約束已經(jīng)在3NF中完成了。
例子,使用關(guān)系表描述學(xué)生、課程、教師的關(guān)系(假定一名教師只負(fù)責(zé)一門(mén)課程,一門(mén)課程則可以由多位教師負(fù)責(zé)):
Student
學(xué)生
|
Course
課程
|
Teacher
教師
|
S1
|
C1
|
T1
|
S1
|
C2
|
T2
|
S2
|
C1
|
T1
|
S2
|
C2
|
T3
|
S2
|
C3
|
T2
|
候選鍵:
{Student,Course}
{Student,Teacher}
因此這里不存在非主屬性,而在主屬性的函數(shù)依賴中,存在Teacher→Course,這屬于違反BCNF的情況。
可是,問(wèn)題是這個(gè)表看起來(lái)還挺正常的啊?!它的毛病在于,我們無(wú)法阻止類(lèi)似最后一行這樣的數(shù)據(jù)插入,而這會(huì)導(dǎo)致與前提“一名教師只負(fù)責(zé)一門(mén)課程”違背。所以我們還是需要將它拆分:
Student
學(xué)生
|
Teacher
教師
|
S1
|
T1
|
S1
|
T2
|
S2
|
T1
|
S2
|
T3
|
Teacher
教師
|
Course
課程
|
T1
|
C1
|
T2
|
C2
|
T3
|
C2
|
這樣,在“Teacher-Course”表中,借助主鍵的幫助,最后可以避免違背“一名教師只負(fù)責(zé)一門(mén)課程”這個(gè)前提。
那么,如果沒(méi)有這樣一個(gè)前提,是初的設(shè)計(jì)是否符合BCNF?目前看來(lái)是的。
真實(shí)的情況可能更為復(fù)雜,下面這個(gè)更接近于我的一些經(jīng)歷:
1)學(xué)生需要學(xué)習(xí)多門(mén)課程
2)一門(mén)課程可能有多位教師負(fù)責(zé)
3)一位教師可能負(fù)責(zé)多門(mén)課程
4)某一班級(jí)的某一課程對(duì)應(yīng)的教師是固定的(一位)
據(jù)此,為了描述學(xué)生、課程、教師三者的關(guān)系,從這一團(tuán)亂麻中最早跳出來(lái)的大概是這樣的表:
Student
學(xué)生
|
Class
班級(jí)
|
Course
課程
|
Teacher
教師
|
|
|
|
|
|
|
|
|
候選鍵:
{Student,Course}
我們可以明顯地看到Student→Class違反了2NF,于是:
Student
學(xué)生
|
Class
班級(jí)
|
|
|
|
|
Class
班級(jí)
|
Course
課程
|
Teacher
教師
|
|
|
|
|
|
|
從這兩張表,仔細(xì)考慮,即便我們通過(guò)Class關(guān)聯(lián)兩張表,還是無(wú)法得出學(xué)生與課程的關(guān)系(只能得出可供該學(xué)生選擇的課程),所以我們需要再添加一張表:
Student
學(xué)生
|
Course
課程
|
|
|
|
|
最后大概是這么三張表,可能還有其它的方案,這里只是舉例說(shuō)明,就不糾纏了。
在BCNF之后,還有4NF,5NF,DKNF,6NF,等什么時(shí)候有空了再看看是什么東東。