數(shù)據(jù)庫第三范式的定義胳螟,是這樣的:
A table is in a third normal form when the following conditions are met -
- It is in second normal form.
- All nonprimary fields are dependent on the primary key.
簡單翻譯過來悬嗓,就是說:
一張遵守第三范式的數(shù)據(jù)庫表,應(yīng)該符合以下兩個(gè)條件:
- 這張表遵守第二范式。
- 這張表中教藻,所有非主屬性都(僅)依賴于主屬性墓捻。
也就是“在第二范式的基礎(chǔ)上,消除了非主屬性對主屬性的傳遞依賴”(https://cloud.tencent.com/developer/article/1625499)交煞。
ps咏窿,雖然我們在建表時(shí)使用的主鍵大多是業(yè)務(wù)無關(guān)的字段(例如自增主鍵),但是在討論數(shù)據(jù)庫范式時(shí)素征,“主屬性”集嵌、“非主屬性”一般都是指的業(yè)務(wù)字段。否則御毅,恐怕沒有一張表是符合第二范式的根欧,更遑論第三范式了。
網(wǎng)上對第三范式的舉例說明可謂比比皆是端蛆,這里就不贅述了凤粗。
我這里要舉的例子有點(diǎn)特別。它不僅僅在表中引入了傳遞依賴今豆,甚至還隱去了傳遞依賴的中間環(huán)節(jié)嫌拣。
簡略一點(diǎn)來說,這張表是這樣的:
CREATE TABLE TB_CONTACTER(
ID INT NOT NULL AUTO_INCREMENT,
USER_ID INT NOT NULL,
CHANNEL_ID VARCHAR(10),
CONTACTER VARCHAR(100),
PRIMARY KEY (ID),
KEY(USER_ID,CHANNEL_ID)
);
這張表的最大問題在于:CONTACTER并不是直接依賴于USER_ID+CHANNEL_ID的晚凿。它們之間存在著這樣的一種傳遞依賴:
USER_ID+CHANNEL_ID --> USER_ID+PRODUCT_ID --> APPLY_ID --> CONTACTER亭罪。
翻譯一下就是這樣的,用戶從某個(gè)渠道進(jìn)入系統(tǒng)歼秽,選擇一個(gè)產(chǎn)品应役,提交一筆申請,并給這個(gè)申請單指定一個(gè)收貨的聯(lián)系人。
這個(gè)依賴確實(shí)有點(diǎn)復(fù)雜箩祥。于是院崇,這張表的設(shè)計(jì)者對它做了一個(gè)簡化處理。
按照當(dāng)時(shí)的業(yè)務(wù)約束袍祖,一個(gè)用戶在一個(gè)渠道上底瓣,都只能選擇一個(gè)產(chǎn)品;針對每個(gè)產(chǎn)品都提交一筆有效申請蕉陋;而這筆申請單上捐凭,只能指定一個(gè)聯(lián)系人。用圖形來表示就是這樣的:
既然這個(gè)依賴鏈?zhǔn)侨绱说匾桓畹树蓿俏覀兙鸵桓妥油钡降缀昧俗鲁ΑS谑牵陀辛饲懊娴腡B_CONTACTER表的設(shè)計(jì)缩举。
可是垦梆,業(yè)務(wù)數(shù)據(jù)之間的依賴關(guān)系是由產(chǎn)品需求定義的。而只要數(shù)一數(shù)產(chǎn)品經(jīng)理有多少次拍胸脯保證“這次的需求不會再改了”仅孩,我們就知道產(chǎn)品需求有多善變托猩。
在如此善變的產(chǎn)品需求面前,讓業(yè)務(wù)數(shù)據(jù)之間的依賴關(guān)系永遠(yuǎn)保持不變辽慕,真是一種奢望京腥。
而這種不切實(shí)際的奢望,很快就讓我們嘗到了苦頭鼻百。
不知道該說不出所料還是該說大出所料绞旅,賴以簡化依賴關(guān)系的業(yè)務(wù)約束被后來的產(chǎn)品需求打破了摆尝,最終——應(yīng)該說是目前——變成了這樣:
一個(gè)用戶不僅可以在多個(gè)渠道上申請同一個(gè)產(chǎn)品温艇;而且在每一個(gè)渠道上,都可以選擇多個(gè)產(chǎn)品堕汞、提交多筆有效申請勺爱;不過每一筆申請單上,仍然只能指定一個(gè)聯(lián)系人讯检。
同樣用圖來表示琐鲁,就是這樣的(注意最左邊的數(shù)據(jù)關(guān)系,從原先的1:1變成了N:M):
于是乎人灼,我們的這張TB_CONTACTER表就出現(xiàn)了一個(gè)問題:無論是根據(jù)USER_ID+CHANNEL_ID围段,還是根據(jù)APPLY_ID,我們都無法準(zhǔn)確地查到申請單上關(guān)聯(lián)的聯(lián)系人了投放。
如果不做改造奈泪,這張表等于是廢了。而真的改造起來,里面有幾百上千萬的存量數(shù)據(jù)涝桅,怎么處理都讓人頭大拜姿。
總結(jié)一下來說,雖然數(shù)據(jù)庫范式算得上很“古老”的技術(shù)思想冯遂,但是俗話說得好蕊肥,姜是老的辣,酒是陳的香蛤肌。能夠經(jīng)歷大浪淘沙壁却、沉淀至今的技術(shù),仍然值得我們認(rèn)真鉆研和嚴(yán)謹(jǐn)使用裸准。