掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
眾所周知,數(shù)據(jù)庫(kù)設(shè)計(jì)的好壞直接關(guān)系到數(shù)據(jù)庫(kù)運(yùn)行的效率。根據(jù)筆者的經(jīng)驗(yàn),對(duì)于提升數(shù)據(jù)庫(kù)性能來(lái)說(shuō),合理的數(shù)據(jù)庫(kù)設(shè)計(jì),比升級(jí)服務(wù)器的硬件配置,還要來(lái)的有效。但是,筆者無(wú)論是在跟同事合作,又或者是在論壇上跟相關(guān)同行交流的時(shí)候,總是會(huì)發(fā)現(xiàn)有些人有一些不好的數(shù)據(jù)庫(kù)設(shè)計(jì)習(xí)慣,影響了數(shù)據(jù)庫(kù)的性能,增加了數(shù)據(jù)庫(kù)管理員的工作量。

員工經(jīng)過(guò)長(zhǎng)期磨合與沉淀,具備了協(xié)作精神,得以通過(guò)團(tuán)隊(duì)的力量開(kāi)發(fā)出優(yōu)質(zhì)的產(chǎn)品。創(chuàng)新互聯(lián)堅(jiān)持“專(zhuān)注、創(chuàng)新、易用”的產(chǎn)品理念,因?yàn)椤皩?zhuān)注所以專(zhuān)業(yè)、創(chuàng)新互聯(lián)網(wǎng)站所以易用所以簡(jiǎn)單”。公司專(zhuān)注于為企業(yè)提供成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、電商網(wǎng)站開(kāi)發(fā),微信小程序,軟件按需定制開(kāi)發(fā)等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。
筆者認(rèn)為,為了提升數(shù)據(jù)庫(kù)的性能,在Oracle數(shù)據(jù)庫(kù)設(shè)計(jì)的時(shí)候,要做到五條法則。
一:在小型表上不要建立索引
毋庸置疑,索引可以提高數(shù)據(jù)庫(kù)查詢(xún)的效率。但是,俗話(huà)說(shuō),過(guò)之則不及。索引也必須用在合時(shí)的地方。如果索引設(shè)置不當(dāng),不但不會(huì)提升數(shù)據(jù)庫(kù)的性能,反而會(huì)起到相反的作用。如在小型數(shù)據(jù)庫(kù)上設(shè)置索引,而且這些表用戶(hù)更改的比較頻繁。如員工基本信息表,就是簡(jiǎn)單的不超過(guò)十個(gè)字段。這個(gè)表用戶(hù)需要經(jīng)常的進(jìn)行插入與刪除操作。當(dāng)進(jìn)行這些變更作業(yè)的時(shí)候,需要對(duì)索引進(jìn)行維護(hù)。而這個(gè)維護(hù)的工作量可能比掃描表空間消耗更多的存儲(chǔ)空間。從而不但起步到改善數(shù)據(jù)庫(kù)性能的作用,反而是在拖后腿。
所以,在數(shù)據(jù)庫(kù)設(shè)計(jì)的時(shí)候,要做到的第一個(gè)戒條就是,不要再用戶(hù)經(jīng)常更改的小型表上建立索引。否則的話(huà),是得不償失的。
二:不要用用戶(hù)的鍵
如我們?cè)谠O(shè)計(jì)一個(gè)ERP系統(tǒng)數(shù)據(jù)庫(kù)的時(shí)候,有一張銷(xiāo)售訂單表。在這張表中,有一個(gè)銷(xiāo)售訂單號(hào)。那么我們能否利用這個(gè)單號(hào)作為關(guān)聯(lián)其他表的外鍵呢?如在銷(xiāo)售出貨單上,需要關(guān)聯(lián)到銷(xiāo)售訂單。這個(gè)時(shí)候,我們能否把銷(xiāo)售訂單單號(hào)作為跟出貨單關(guān)聯(lián)的關(guān)鍵字呢?
答案是可以的,但是不是最優(yōu)選擇。我們可以看一下ERP的后臺(tái)數(shù)據(jù)庫(kù)。在銷(xiāo)售訂單表上,除了銷(xiāo)售訂單號(hào)這個(gè)唯一表示銷(xiāo)售訂單紀(jì)錄的字段外,還有一個(gè)字段就是銷(xiāo)售訂單ID。在前臺(tái)的出貨單界面上雖然顯示的是銷(xiāo)售訂單號(hào)碼,但是,在后臺(tái)卻存儲(chǔ)著的是銷(xiāo)售訂單ID。也就是說(shuō),數(shù)據(jù)庫(kù)不是以用戶(hù)的鍵作為主鍵,而是采用了數(shù)據(jù)庫(kù)自動(dòng)維護(hù)的單據(jù)ID這個(gè)字段。
為什么要這么設(shè)計(jì)呢?這就是筆者今天要談的第二個(gè)戒條,不要用用戶(hù)的鍵。通常情況下,不要選擇用戶(hù)可編輯的字段作為外鍵或者主鍵。因?yàn)檫@會(huì)增加我們額外的工作量。
如果我們把銷(xiāo)售訂單號(hào)作為外鍵的話(huà),則在創(chuàng)建銷(xiāo)售訂單紀(jì)錄后還要對(duì)用戶(hù)編輯字段的行為施加限制,如判斷是否違反外鍵的強(qiáng)制性規(guī)則等等。有些系統(tǒng)把銷(xiāo)售訂單號(hào)設(shè)置為外鍵的話(huà),則往往是把這個(gè)字段設(shè)置為系統(tǒng)自動(dòng)編號(hào),并且用戶(hù)不可更改??墒牵趯?shí)際工作中,企業(yè)員工往往需要編輯這個(gè)字段。員工需要編輯這些不可編輯的字段時(shí)系統(tǒng)缺乏靈活性的缺陷就體現(xiàn)出來(lái)了。而且,當(dāng)用戶(hù)輸入完數(shù)據(jù)保存的時(shí)候再提示紀(jì)錄不符合要求,則也不是很人性化的設(shè)計(jì)。
另外,我們還必須為此設(shè)計(jì)一些檢測(cè)和糾正鍵沖突的方法。如考慮這個(gè)外鍵的直是否在其他數(shù)據(jù)表中存在等等。雖然這通常只需要我們花點(diǎn)時(shí)間就可以搞定。但是從數(shù)據(jù)庫(kù)性能上來(lái)說(shuō),這個(gè)代價(jià)就比較大了。再則,如此的話(huà),就不能夠很好的把系統(tǒng)的基本數(shù)據(jù)跟企業(yè)員工的數(shù)據(jù)實(shí)現(xiàn)很好的隔離。
所以,筆者認(rèn)為,不要用用戶(hù)的鍵來(lái)作為我們數(shù)據(jù)庫(kù)設(shè)計(jì)的主鍵或則外鍵?;蛘哒f(shuō),數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí)用到的鍵要讓數(shù)據(jù)庫(kù)系統(tǒng)進(jìn)行自動(dòng)維護(hù),用戶(hù)不得更改這個(gè)維護(hù)規(guī)則。
三:不要用商務(wù)規(guī)則來(lái)實(shí)現(xiàn)數(shù)據(jù)的完整性
數(shù)據(jù)的完整性有好幾種實(shí)現(xiàn)方法。如可以通過(guò)數(shù)據(jù)庫(kù)約束實(shí)現(xiàn)數(shù)據(jù)完整性;也可以通過(guò)前臺(tái)系統(tǒng)的商務(wù)規(guī)則來(lái)實(shí)現(xiàn)數(shù)據(jù)的完整性。不過(guò),筆者這里要建議的是,在一些大型的數(shù)據(jù)庫(kù)中,不要試圖通過(guò)商務(wù)規(guī)則來(lái)實(shí)現(xiàn)數(shù)據(jù)的完整性,而盡可能的通過(guò)數(shù)據(jù)庫(kù)的約束來(lái)實(shí)現(xiàn)。因?yàn)槿敉ㄟ^(guò)商務(wù)規(guī)則來(lái)實(shí)現(xiàn)完整性,往往會(huì)出現(xiàn)一些莫名其妙的錯(cuò)誤。
如筆者就遇到過(guò)這一個(gè)案例。在數(shù)據(jù)庫(kù)設(shè)計(jì)的時(shí)候,把某個(gè)字符型字段長(zhǎng)度限制為最長(zhǎng)50位。而在前臺(tái)應(yīng)用程序中,卻限制了60位。在員工數(shù)據(jù)數(shù)據(jù)的時(shí)候,在前臺(tái)應(yīng)用程序中,可以輸入55個(gè)字符。但是,下次用戶(hù)查詢(xún)的時(shí)候,卻發(fā)現(xiàn)后面幾個(gè)字符沒(méi)有了,只剩下前面那些內(nèi)容。這主要是因?yàn)樵跀?shù)據(jù)保存的時(shí)候,超過(guò)了數(shù)據(jù)庫(kù)的最長(zhǎng)位數(shù)限制。數(shù)據(jù)庫(kù)就會(huì)自動(dòng)把后面幾個(gè)字符去掉然后保存。如此,用戶(hù)在前臺(tái)輸入數(shù)據(jù)的時(shí)候,以為可以保存。但是,實(shí)際上數(shù)據(jù)庫(kù)中存儲(chǔ)的數(shù)據(jù)是不全的。
所以,筆者的第三個(gè)戒條就是,不要利用商務(wù)規(guī)則在前臺(tái)實(shí)現(xiàn)數(shù)據(jù)的完整性。只要有可能,就要盡量在數(shù)據(jù)庫(kù)系統(tǒng)層面實(shí)現(xiàn)數(shù)據(jù)的完整性。在數(shù)據(jù)庫(kù)層面實(shí)現(xiàn)數(shù)據(jù)完整性的同時(shí),需要注意用戶(hù)的友好性。
一是要把違反約束信息盡可能詳細(xì)的回饋給用戶(hù)。如銷(xiāo)售訂單號(hào),在數(shù)據(jù)庫(kù)系統(tǒng)中設(shè)置了唯一性約束。則當(dāng)用戶(hù)在建立銷(xiāo)售訂單的時(shí)候,銷(xiāo)售訂單號(hào)重復(fù)時(shí),就需要把這個(gè)約束的詳細(xì)信息反饋給前臺(tái)用戶(hù)。若只顯示不能夠保存這個(gè)錯(cuò)誤信息往往是不夠的。這會(huì)讓用戶(hù)摸不著頭腦。
二是在必要的時(shí)候,可以利用觸發(fā)器來(lái)實(shí)現(xiàn)數(shù)據(jù)的完整性。雖然在功能設(shè)計(jì)上,我們不建議在Oracle數(shù)據(jù)庫(kù)中采用觸發(fā)器來(lái)實(shí)現(xiàn)。如要把某個(gè)小寫(xiě)金額轉(zhuǎn)換為大小金額。我們是建議通過(guò)前臺(tái)應(yīng)用程序?qū)崿F(xiàn)。因?yàn)閼?yīng)用程序的執(zhí)行效率要比數(shù)據(jù)庫(kù)的觸發(fā)器高。但是,在數(shù)據(jù)庫(kù)數(shù)據(jù)完整性上,在必要的時(shí)候,若靠數(shù)據(jù)庫(kù)約束無(wú)法實(shí)現(xiàn)完整性,我們?nèi)匀唤ㄗh采用觸發(fā)器,而不是前臺(tái)應(yīng)用程序來(lái)實(shí)現(xiàn)。在任何情況下,不要依賴(lài)于應(yīng)用程序來(lái)實(shí)現(xiàn)數(shù)據(jù)完整性。否則的話(huà),很難保證數(shù)據(jù)庫(kù)約束與商務(wù)層約束的一致性。
四:在可能的情況下,不要讓前臺(tái)應(yīng)用程序直接訪(fǎng)問(wèn)數(shù)據(jù)表
其實(shí),在數(shù)據(jù)庫(kù)基礎(chǔ)表與前臺(tái)應(yīng)用程序之間,還有一個(gè)很好的“中間人”,那就是視圖。試圖是數(shù)據(jù)庫(kù)基礎(chǔ)表的一個(gè)抽象。他除了可以保障數(shù)據(jù)的質(zhì)量外,還可以有效的訪(fǎng)問(wèn)前臺(tái)應(yīng)用程序?qū)τ跀?shù)據(jù)的非法訪(fǎng)問(wèn)。所以,一些安全性級(jí)別比較高的數(shù)據(jù)庫(kù)系統(tǒng),在數(shù)據(jù)庫(kù)設(shè)計(jì)的時(shí)候,往往會(huì)在數(shù)據(jù)庫(kù)和前臺(tái)應(yīng)用程序代碼之間提供“視圖”這個(gè)中間人,讓其作為基礎(chǔ)表的“新聞發(fā)言人”。如此,前臺(tái)應(yīng)用程序在沒(méi)有必要的情況下,可以不直接訪(fǎng)問(wèn)數(shù)據(jù)表,而是通過(guò)視圖來(lái)對(duì)表實(shí)現(xiàn)間接的訪(fǎng)問(wèn)。
如在進(jìn)行數(shù)據(jù)導(dǎo)入程序設(shè)計(jì)的時(shí)候,通過(guò)視圖來(lái)實(shí)現(xiàn)則是一個(gè)很理想的方法。如用戶(hù)現(xiàn)在要導(dǎo)入產(chǎn)品信息,包括產(chǎn)品基本信息、供應(yīng)商信息、價(jià)格信息等等。這些信息在數(shù)據(jù)庫(kù)中往往包含在三種表中,分別為產(chǎn)品基本信息表、供應(yīng)商信息表、產(chǎn)品價(jià)格信息表。若前臺(tái)應(yīng)用程序直接訪(fǎng)問(wèn)基礎(chǔ)表的話(huà),就需要分別訪(fǎng)問(wèn)這三張基礎(chǔ)表。這不但效率比較低,而且也不容易實(shí)現(xiàn)數(shù)據(jù)的完整性。此時(shí),我們就可以利用視圖,把一些必須要填入的字段組合在一張可更新視圖中。如此,前臺(tái)應(yīng)用程序只需要訪(fǎng)問(wèn)一個(gè)數(shù)據(jù)庫(kù)對(duì)象即可。
再者,在數(shù)據(jù)庫(kù)報(bào)表設(shè)計(jì)上,更是要通過(guò)視圖來(lái)實(shí)現(xiàn)。而不要通過(guò)傳遞一段SQL代碼來(lái)查詢(xún)基礎(chǔ)表。這對(duì)于數(shù)據(jù)的安全性會(huì)帶來(lái)比較大的威脅。
所以,第四條法則就是,在可能的情況下,不要讓前臺(tái)應(yīng)用程序直接訪(fǎng)問(wèn)數(shù)據(jù)表。
五:不要一直讓用戶(hù)輸入數(shù)據(jù)
有些字段其實(shí)不一定要讓用戶(hù)輸入,只需要用戶(hù)選擇即可。如在人事管理系統(tǒng)中,企業(yè)員工所屬的民族、職位、省份等等就沒(méi)有必要讓用戶(hù)手工輸入。而可以通過(guò)列表的形式讓員工來(lái)進(jìn)行選擇。這種手段,是提高數(shù)據(jù)完整性的最佳方式之一。若能夠給用戶(hù)提供一個(gè)詳細(xì)的列表供其選擇,這樣將減少鍵入代碼的錯(cuò)誤,同時(shí)提高數(shù)據(jù)庫(kù)的一致性;也可以提高用戶(hù)界面的友好性。
所以,在數(shù)據(jù)庫(kù)設(shè)計(jì)的時(shí)候,盡量使用列表字段來(lái)供用戶(hù)選擇。若連省份等等字段都要用戶(hù)手工輸入的話(huà),則我們?cè)跀?shù)據(jù)庫(kù)完整性所花費(fèi)的時(shí)間,就要很多。如在數(shù)據(jù)保存的時(shí)候,都要去判斷用戶(hù)輸入的數(shù)據(jù)是否合乎完整性的規(guī)則。這顯然工作量要比設(shè)計(jì)一個(gè)列表字段多得多。
故數(shù)據(jù)庫(kù)設(shè)計(jì)的第五條法則就是不要老是讓用戶(hù)手工輸入數(shù)據(jù)。提供列表讓用戶(hù)進(jìn)行選擇,用戶(hù)不僅可以提高效率,我們也可以省事,同時(shí),也能夠保障數(shù)據(jù)的準(zhǔn)確率。
【編輯推薦】

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流