数据库设计注意事项和原则
引言數(shù)據(jù)庫設(shè)計是信息系統(tǒng)設(shè)計的基礎(chǔ),一個好的數(shù)據(jù)庫設(shè)計在滿足了軟件需求之外,還要易維護、易擴充等等要求。當(dāng)然,對專家們反復(fù)強調(diào)的數(shù)據(jù)的一致性、冗余性、訪問效率等問題的解決,很大程度上取決于數(shù)據(jù)庫設(shè)計者的經(jīng)驗和專業(yè)水平。但這不妨礙我們根據(jù)過去的經(jīng)驗,從實用的角度給出數(shù)據(jù)庫設(shè)計所要要考慮的問題并盡可能給出相應(yīng)的解決方案,從而給信息系統(tǒng)的數(shù)據(jù)庫設(shè)計者一些有益的啟示。(注:這里的數(shù)據(jù)庫設(shè)計主要指數(shù)據(jù)庫中表和視圖的schema設(shè)計,不涉足數(shù)據(jù)庫系統(tǒng)中其他方面的設(shè)計)那么怎樣才算是一個好的數(shù)據(jù)庫設(shè)計呢?以下給出一個一般性的標(biāo)準(zhǔn)。
一、一個好的數(shù)據(jù)庫設(shè)計首先要滿足用戶的需求
所有信息系統(tǒng)最后都將提交給最終用戶使用,對于這一點,相信大家都已經(jīng)達成共識。但是準(zhǔn)確地把握用戶的需求是很難的,雖然各方面的專家已經(jīng)從不同方面給出了解決方案,但是用戶需求仍然是軟件工程中最不確定的因素之一。
二、一個好的數(shù)據(jù)庫設(shè)計要便于維護和擴充
為了應(yīng)對用戶需求的修改和添加,也為了滿足各種不同的軟硬件環(huán)境下系統(tǒng)的使用,大部分信息系統(tǒng)都不得不在其生命期中進行升級和調(diào)整。在這些升級、調(diào)整中,又有相當(dāng)部分會涉及到數(shù)據(jù)庫設(shè)計的修改,因此,數(shù)據(jù)庫設(shè)計最好從一開始就能在易維護、可擴充的角度多加斟酌。
1、不要為各種編號字段的設(shè)定固定的意義
而是最好通過對照表來建立這種編號和意義的對照關(guān)系。舉例來說,很多設(shè)計者習(xí)慣給部門信息給出固定的編號,這種設(shè)計有個致命的缺陷:那就是由于這種對照關(guān)系既然不體現(xiàn)在數(shù)據(jù)庫中,就必然要用業(yè)務(wù)邏輯來進行解釋,這樣一來,一有新的調(diào)整就不得不更新業(yè)務(wù)邏輯代碼,也就非常容易不一致的錯誤。
2、枚舉信息要體現(xiàn)在相應(yīng)在對照表中
而不是體現(xiàn)在使用該信息的表中的值字段,這樣做的好處是當(dāng)用戶希望用該枚舉信息作為查詢條件的時候,通過參照表的方式可以很容易的建立這些信息,另外也避免了當(dāng)多個表格中都含有該枚舉信息有可能引起的不一致。
3、用關(guān)聯(lián)表建立表和表之間的多對多關(guān)系
而不要用一個字段解析的方式進行,舉例來說,為了描述用戶(UserInfo)和角色(RoleInfo)之間的關(guān)聯(lián)關(guān)系,我們要建立對照表UserInfo_RoleInfo,而不要試圖在用戶表中建立一個較長的字段,如Roles(用RoleID1;RoleID2…的形式構(gòu)成)來代替,因為這樣一來字段解釋需要在業(yè)務(wù)代碼相應(yīng)的解析代碼,二來由于Roles定長,無法滿足用戶角色的擴充。
三、一個好的數(shù)據(jù)庫設(shè)計要具有“可讀性”
如同編程書籍中反復(fù)強調(diào)的程序員一定要在代碼的可讀性方面下功夫一樣,考慮到信息系統(tǒng)將來的升級和維護可能要要由另外一批人來進行,因此數(shù)據(jù)庫設(shè)計必然也要具有可理解性。對此,我們參照提高代碼可讀性的常用方法,給出一些建議:
1、用設(shè)計文檔來提高數(shù)據(jù)庫設(shè)計的可讀性
這點基本對應(yīng)于“可讀性”代碼里面的注釋。在一個合格的數(shù)據(jù)庫設(shè)計文檔中必須給出數(shù)據(jù)庫中的每個表、每個字段、表間的關(guān)聯(lián)關(guān)系以及各種約束的意義以及由來,從而有可能讓開發(fā)者根據(jù)用戶需求和設(shè)計文檔就能理解正確數(shù)據(jù)庫的設(shè)計。
2、給表和視圖起一個有意義的名字
這點對應(yīng)于coding規(guī)范中的變量和函數(shù)的命名,很顯然,CustomerInfo的名字很容易聯(lián)想到該表中含有客戶信息,而把它命名為Table0001只能讓人感到費解外。另外,如果DBMS提供表和視圖名的大小寫支持,該名稱最好由每個構(gòu)成單詞(首字母大寫)拼接而成。
3、用前綴給出表和視圖內(nèi)容之外的其他信息
如給參照表Ref_前綴,這樣就可以讓業(yè)務(wù)邏輯實現(xiàn)人員根據(jù)表的名字知道他所要操作的是不是張參照表,從而幫助他更快地理解詳細(xì)設(shè)計,并有可能及早發(fā)現(xiàn)里面的錯誤。同樣,給所有視圖加上V_前綴,就可以讓業(yè)務(wù)邏輯編程者很容易地知道他現(xiàn)在面臨的是一個表還是視圖,從而避免了對視圖進行更新操作這種低級的錯誤。
4、給每一個字段起一個有意義的名字
如給CustomerInfo表中的電子郵件字段起名EMail讓人很容易明白它的準(zhǔn)確含義,而Field05則讓人不知所云。基于同樣的道理,數(shù)據(jù)庫設(shè)計中也不能給字段起一個張冠李戴的名字。
5、字段命名要考慮上下文
舉例來說,在UserInfo表中,用UserName來表示用戶名字段就不如Name來的更加合適。這種情況畫蛇添足的情況在對照表的設(shè)計中體現(xiàn)得尤為明顯,如把部門對照表(Ref_Department)中的部門ID字段命名為DepartmentID,把部門名稱字段命名為DepartmentName等等。
6、視圖的設(shè)計不要牽扯到其他視圖
與代碼設(shè)計中函數(shù)調(diào)用最好不要嵌套過多層次相對應(yīng),為了便于數(shù)據(jù)庫設(shè)計的閱讀人能夠很好地理解設(shè)計,視圖最好直接建立在表上。
7、同一表中的記錄最好不要相互引用
這種引用關(guān)系不僅讓數(shù)據(jù)庫設(shè)計的閱讀人云里霧里,也不便于業(yè)務(wù)邏輯代碼的編寫。
8、關(guān)聯(lián)表的命名用關(guān)聯(lián)的表名中間加下劃線連接構(gòu)成
如學(xué)生(StudentInfo)和課程(CourseInfo)的關(guān)聯(lián)表起名StudentInfo_CourseInfo。
四、一個好的數(shù)據(jù)庫設(shè)計能夠滿足空間和效率的要求
對于一個信息系統(tǒng)來說,在實現(xiàn)用戶需求的基礎(chǔ)之上,保證一個較低的空間占用以及短的響應(yīng)時間都是理智的客戶所愿意看到的。那么在這一方面,數(shù)據(jù)庫設(shè)計又要做些什么工作呢?
1、使用varchar而不要使用char字段
對于不定長信息如用戶的簡介信息,varchar的使用可以減少近一半的空間占用。當(dāng)然這點不能一概而論,如用相應(yīng)長度的char存儲定長文本數(shù)據(jù)就比varchar來的合適。
2、不要使用BLOB字段存放“大數(shù)據(jù)”
BLOB字段誠如其名,本身是為存儲二進制大數(shù)據(jù)而出現(xiàn)的,同樣的道理也適用于某些DBMS所引入的TEXT字段。因為對于一般信息系統(tǒng)而言,最長的字段往往是一些描述文本信息,而DBMS對char/varchar的長度基本能滿足這種需求。因此積極建議設(shè)計者對一些貌似很長的文本的最大允許長度進行確認(rèn),在此基礎(chǔ)上參照DBMS中的開發(fā)手冊來決定是否采用大字段。
3、不要使用設(shè)計器缺省的字段長度
這種做法一方面縱容了設(shè)計者對用戶需求的一知半解以及對設(shè)計敷衍了事的不良習(xí)慣,另外一方面也在數(shù)據(jù)的存儲上浪費了不少的空間,因為使用缺省字段長度的情況往往發(fā)生在字段上。
4、不要輕易使用unicode文本字段
DBMS對unicode的支持在幫助產(chǎn)品國際化的同時,也在一定程度上帶來空間上的浪費,尤其是在當(dāng)要存儲的文本中的基本都是ASCII字符的情況下,這種浪費尤為明顯。因此,建議設(shè)計者在選擇unicode的理由,一定是出于國際化的考慮,而不是其他。因為大多數(shù)的大字符集和ASCII字符并存情況下所要碰到的問題基本上都已經(jīng)由DBMS提供商解決。
5、使用預(yù)計算表來提高響應(yīng)速度
跟數(shù)據(jù)倉庫里面的某些思路相似,當(dāng)業(yè)務(wù)邏輯中需要用倒根據(jù)歷史信息得來的統(tǒng)計數(shù)據(jù)時,最好由獨立于系統(tǒng)的預(yù)計算模塊或相應(yīng)的DW工具定期完成這些統(tǒng)計數(shù)據(jù)的預(yù)計算。
五、一個好的數(shù)據(jù)庫設(shè)計可以簡化業(yè)務(wù)邏輯的設(shè)計
所有的數(shù)據(jù)庫設(shè)計都不是孤立的,它通過相應(yīng)的業(yè)務(wù)邏輯實現(xiàn)(三層結(jié)構(gòu)中還有表現(xiàn)層)來形成最終的產(chǎn)品,因此一個好的數(shù)據(jù)庫設(shè)計應(yīng)該能夠幫助降低業(yè)務(wù)邏輯的編寫難度,最起碼不要給業(yè)務(wù)邏輯的設(shè)計、編碼帶來額外工作。
1、所有允許為空的字段必須是基于用戶需求,而不是出于設(shè)計上方便的考慮。這樣帶來的好處是讓詳細(xì)設(shè)計中的某些錯誤和疏漏(如在設(shè)計中沒有考慮對非空字段的內(nèi)容檢查)在編碼和單元測試階段就被發(fā)現(xiàn),從而避免了進一步擴散,有助于提高軟件的質(zhì)量。
2、不要業(yè)務(wù)邏輯代碼實現(xiàn)唯一性約束
對數(shù)據(jù)庫表中的某些字段(或者多個字段的組合)的唯一性約束應(yīng)該盡可能地加到數(shù)據(jù)庫端。因為這種約束工作交給業(yè)務(wù)邏輯中去實現(xiàn)代價高昂而且不可靠。
3、關(guān)聯(lián)約束一定要建立在數(shù)據(jù)庫端
分析出設(shè)計中所涉及的主外鍵引用關(guān)系并體現(xiàn)在數(shù)據(jù)庫設(shè)計中。這一條出于兩點考慮:降低業(yè)務(wù)邏輯的編寫難度和數(shù)據(jù)關(guān)聯(lián)性約束的要求。
總結(jié)
以上是生活随笔為你收集整理的数据库设计注意事项和原则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql每个月每个人的花销占比_11月:每
- 下一篇: oracle .dbf文件过大_学习这篇