在日常的數(shù)據(jù)庫(kù)開(kāi)發(fā)過(guò)程中,很多開(kāi)發(fā)者一參與到數(shù)據(jù)庫(kù)設(shè)計(jì),就會(huì)很自然地把 “三范式” 當(dāng)作自己的信條。他們往往認(rèn)為遵循這個(gè)規(guī)范就是數(shù)據(jù)庫(kù)設(shè)計(jì)的唯一標(biāo)準(zhǔn)。由于這種心態(tài),他們往往盡管一路碰壁也會(huì)堅(jiān)持把項(xiàng)目做下去。
對(duì)于這種現(xiàn)象,中培偉業(yè)《 Oracle數(shù)據(jù)庫(kù)管理與性能調(diào)優(yōu)實(shí)踐》培訓(xùn)專家袁老師指出,一些規(guī)范當(dāng)然很重要,但是不需要死記硬背,只要掌握一些規(guī)則即可。袁老師在這里分享了11個(gè)在數(shù)據(jù)庫(kù)設(shè)計(jì)過(guò)程中應(yīng)該遵守的規(guī)則。
規(guī)則 1:弄清楚將要開(kāi)發(fā)的應(yīng)用程序是什么性質(zhì)的(OLTP 還是 OPAP)?
當(dāng)你要開(kāi)始設(shè)計(jì)一個(gè)數(shù)據(jù)庫(kù)的時(shí)候,你應(yīng)該首先要分析出你為之設(shè)計(jì)的應(yīng)用程序是什么類型的,它是 “事務(wù)處理型”(Transactional) 的還是 “分析型” (Analytical)的?你會(huì)發(fā)現(xiàn)許多開(kāi)發(fā)人員采用標(biāo)準(zhǔn)化做法去設(shè)計(jì)數(shù)據(jù)庫(kù),而不考慮目標(biāo)程序是什么類型的,這樣做出來(lái)的程序很快就會(huì)陷入性能、客戶定制化的問(wèn)題當(dāng)中。正如前面所說(shuō)的,這里有兩種應(yīng)用程序類型, “基于事務(wù)處理” 和 “基于分析”
規(guī)則 2:將你的數(shù)據(jù)按照邏輯意義分成不同的塊,讓事情做起來(lái)更簡(jiǎn)單
這個(gè)規(guī)則其實(shí)就是 “三范式” 中的第一范式。違反這條規(guī)則的一個(gè)標(biāo)志就是,你的查詢使用了很多字符串解析函數(shù)
規(guī)則 3:不要過(guò)度使用 “規(guī)則 2”
開(kāi)發(fā)者都是一群很可愛(ài)的生物。如果你告訴他們這是一條解決問(wèn)題的正路,他們就會(huì)一直這么做下去,做到過(guò)了頭導(dǎo)致了一些不必要的后果。這也可以應(yīng)用于我們剛剛在前面提到的規(guī)則2。當(dāng)你考慮字段分解時(shí),先暫停一下,并且問(wèn)問(wèn)你自己是否真的需要這么做。正如所說(shuō)的,分解應(yīng)該是要符合邏輯的。
規(guī)則 4:把重復(fù)、不統(tǒng)一的數(shù)據(jù)當(dāng)成你最大的敵人來(lái)對(duì)待
集中那些重復(fù)的數(shù)據(jù)然后重構(gòu)它們。我個(gè)人更加擔(dān)心的是這些重復(fù)數(shù)據(jù)帶來(lái)的混亂而不是它們占用了多少磁盤空間。
規(guī)則 5:當(dāng)心被分隔符分割的數(shù)據(jù),它們違反了“字段不可再分”
前面的規(guī)則 2 即“第一范式”說(shuō)的是避免 “重復(fù)組” 。這些被塞滿了分隔符的數(shù)據(jù)列需要特別注意,并且一個(gè)較好的辦法是將這些字段移到另外一個(gè)表中,使用外鍵連接過(guò)去,同樣地以便于更好的管理。
規(guī)則 6:當(dāng)心那些僅僅部分依賴主鍵的列
留心注意那些僅僅部分依賴主鍵的列。你可以看到我們是如何移動(dòng) syllabus(課程)字段并且同樣地附上 Standard 表。這條規(guī)則只不過(guò)是 “三范式” 里的 “第二范式”:“所有字段都必須完整地依賴主鍵而不是部分依賴”。
規(guī)則 7:仔細(xì)地選擇派生列
如果你正在開(kāi)發(fā)一個(gè) OLTP 型的應(yīng)用程序,那強(qiáng)制不去使用派生字段會(huì)是一個(gè)很好的思路,除非有迫切的性能要求,比如經(jīng)常需要求和、計(jì)算的 OLAP 程序,為了性能,這些派生字段就有必要存在了。
規(guī)則 8:如果性能是關(guān)鍵,不要固執(zhí)地去避免冗余
不要把 “避免冗余” 當(dāng)作是一條絕對(duì)的規(guī)則去遵循。如果對(duì)性能有迫切的需求,考慮一下打破常規(guī)。常規(guī)情況下你需要做多個(gè)表的連接操作,而在非常規(guī)的情況下這樣的多表連接是會(huì)大大地降低性能的。
規(guī)則 9:多維數(shù)據(jù)是各種不同數(shù)據(jù)的聚合
OLAP 項(xiàng)目主要是解決多維數(shù)據(jù)問(wèn)題。比如你可以看看下面這個(gè)圖表,你會(huì)想拿到每個(gè)國(guó)家、每個(gè)顧客、每段時(shí)期的銷售額情況。簡(jiǎn)單的說(shuō)你正在看的銷售額數(shù)據(jù)包含了三個(gè)維度的交叉。
為這種情況做一個(gè)實(shí)際的設(shè)計(jì)是一個(gè)更好的辦法。簡(jiǎn)單的說(shuō),你可以創(chuàng)建一個(gè)簡(jiǎn)單的主要銷售表,它包含了銷售額字段,通過(guò)外鍵將其他所有不同維度的表連接起來(lái)。
規(guī)則 10:將那些具有“名值表”特點(diǎn)的表統(tǒng)一起來(lái)設(shè)計(jì)
這種 “名值表”往往比較常見(jiàn) “名值表” 意味著它有一些鍵,這些鍵被其他數(shù)據(jù)關(guān)聯(lián)著。
規(guī)則 11:無(wú)限分級(jí)結(jié)構(gòu)的數(shù)據(jù),引用自己的主鍵作為外鍵
我們會(huì)經(jīng)常碰到一些無(wú)限父子分級(jí)結(jié)構(gòu)的數(shù)據(jù)(樹(shù)形結(jié)構(gòu)?)。例如考慮一個(gè)多級(jí)銷售方案的情況,一個(gè)銷售人員之下可以有多個(gè)銷售人員。注意到都是 “銷售人員” 。也就是說(shuō)數(shù)據(jù)本身都是一種。但是層級(jí)不同。這時(shí)候我們可以引用自己的主鍵作為外鍵來(lái)表達(dá)這種層級(jí)關(guān)系,從而達(dá)成目的。