數(shù)據(jù)庫經(jīng)驗(yàn)與技巧《華夏印刷培訓(xùn)招聘網(wǎng)》 轉(zhuǎn)載
一個(gè)成功的管理系統(tǒng),是由:[50% 的業(yè)務(wù) + 50% 的軟件] 所組成,
而 50% 的成功軟件又有 [25% 的數(shù)據(jù)庫 + 25% 的程序] 所組成,數(shù)據(jù)庫設(shè)計(jì)的好壞是一個(gè)關(guān)鍵。
如果把企業(yè)的數(shù)據(jù)比做生命所必需的血液,那么數(shù)據(jù)庫的設(shè)計(jì)就是應(yīng)用中最重要的一部分。
有關(guān)數(shù)據(jù)庫設(shè)計(jì)的材料汗牛充棟,大學(xué)學(xué)位課程里也有專門的講述。
不過,就如我們反復(fù)強(qiáng)調(diào)的那樣,再好的老師也比不過經(jīng)驗(yàn)的教誨。
所以我歸納歷年來所走的彎路及體會,并在網(wǎng)上找了些對數(shù)據(jù)庫設(shè)計(jì)頗有造詣的專業(yè)人士給大家傳授一些設(shè)計(jì)數(shù)據(jù)庫的技巧和經(jīng)驗(yàn)。
精選了其中的 60 個(gè)最佳技巧,并把這些技巧編寫成了本文,為了方便索引其內(nèi)容劃分為 5 個(gè)部分:
第 1 部分 - 設(shè)計(jì)數(shù)據(jù)庫之前
這一部分羅列了 12 個(gè)基本技巧,包括命名規(guī)范和明確業(yè)務(wù)需求等。
第 2 部分 - 設(shè)計(jì)數(shù)據(jù)庫表
總共 24 個(gè)指南性技巧,涵蓋表內(nèi)字段設(shè)計(jì)以及應(yīng)該避免的常見問題等。
第 3 部分 - 選擇鍵
怎么選擇鍵呢?這里有 10 個(gè)技巧專門涉及系統(tǒng)生成的主鍵的正確用法,還有何 時(shí)以及如何索引字段以獲得最佳性能等。
第 4 部分 - 保證數(shù)據(jù)完整性
討論如何保持?jǐn)?shù)據(jù)庫的清晰和健壯,如何把有害數(shù)據(jù)降低到最小程度。
第 5 部分 - 各種小技巧
不包括在以上 4 個(gè)部分中的其他技巧,五花八門,有了它們希望你的數(shù)據(jù)庫開發(fā)工作會更輕松一些。
第 1 部分 - 設(shè)計(jì)數(shù)據(jù)庫之前
考察現(xiàn)有環(huán)境
在設(shè)計(jì)一個(gè)新數(shù)據(jù)庫時(shí),你不但應(yīng)該仔細(xì)研究業(yè)務(wù)需求而且還要考察現(xiàn)有的系統(tǒng)。大多數(shù)數(shù)據(jù)庫項(xiàng)目都不是從頭開始建立的;通常,機(jī)構(gòu)內(nèi)總會存在用來滿足特定需求的現(xiàn)有系統(tǒng)(可能沒有實(shí)現(xiàn)自動計(jì)算)。顯然,現(xiàn)有系統(tǒng)并不完美,否則你就不必再建立新系統(tǒng)了。但是對舊系統(tǒng)的研究可以讓你發(fā)現(xiàn)一些可能會忽略的細(xì)微問題。一般來說,考察現(xiàn)有系統(tǒng)對你絕對有好處。
定義標(biāo)準(zhǔn)的對象命名規(guī)范
一定要定義數(shù)據(jù)庫對象的命名規(guī)范。對數(shù)據(jù)庫表來說,從項(xiàng)目一開始就要確定表名是采用復(fù)數(shù)還是單數(shù)形式。此外還要給表的別名定義簡單規(guī)則(比方說,如果表名是一個(gè)單詞,別名就取單詞的前 4 個(gè)字母;如果表名是兩個(gè)單詞,就各取兩個(gè)單詞的前兩個(gè)字母組成 4 個(gè)字母長的別名;如果表的名字由 3 個(gè)單詞組成,你不妨從頭兩個(gè)單詞中各取一個(gè)然后從最后一個(gè)單詞中再取出兩個(gè)字母,結(jié)果還是組成 4 字母長的別名,其余依次類推)對工作用表來說,表名可以加上前綴 WORK_ 后面附上采用該表的應(yīng)用程序的名字。表內(nèi)的列[字段]要針對鍵采用一整套設(shè)計(jì)規(guī)則。比如,如果鍵是數(shù)字類型,你可以用 _N 作為后綴;如果是字符類型則可以采用 _C 后綴。對列[字段]名應(yīng)該采用標(biāo)準(zhǔn)的前綴和后綴。再如,假如你的表里有好多"money"字段,你不妨給每個(gè)列[字段]增加一個(gè) _M 后綴。還有,日期列[字段]最好以 D_ 作為名字打頭。
檢查表名、報(bào)表名和查詢名之間的命名規(guī)范。你可能會很快就被這些不同的數(shù)據(jù)庫要素的名稱搞糊涂了。假如你堅(jiān)持統(tǒng)一地命名這些數(shù)據(jù)庫的不同組成部分,至少你應(yīng)該在這些對象名字的開頭用 Table、Query 或者 Report 等前綴加以區(qū)別。
如果采用了 Microsoft Access,你可以用 qry、rpt、tbl 和 mod 等符號來標(biāo)識對象(比如 tbl_Employees)。我在和 SQL Server 打交道的時(shí)候還用過 tbl 來索引表,但我用 sp_company (現(xiàn)在用 sp_feft_)標(biāo)識存儲過程,因?yàn)樵谟械臅r(shí)候如果我發(fā)現(xiàn)了更好的處理辦法往往會保存好幾個(gè)拷貝。我在實(shí)現(xiàn) SQL Server 2000 時(shí)用 udf_ (或者類似的標(biāo)記)標(biāo)識我編寫的函數(shù)。
工欲善其事, 必先利其器
采用理想的數(shù)據(jù)庫設(shè)計(jì)工具,比如:SyBase 公司的 PowerDesign,她支持 PB、VB、Delphe 等語言,通過 ODBC 可以連接市面上流行的 30 多個(gè)數(shù)據(jù)庫,包括 dBase、FoxPro、VFP、SQL Server 等,今后有機(jī)會我將著重介紹 PowerDesign 的使用。
獲取數(shù)據(jù)模式資源手冊
正在尋求示例模式的人可以閱讀《數(shù)據(jù)模式資源手冊》一書,該書由 Len Silverston、W. H. Inmon 和 Kent Graziano 編寫,是一本值得擁有的最佳數(shù)據(jù)建模圖書。該書包括的章節(jié)涵蓋多種數(shù)據(jù)領(lǐng)域,比如人員、機(jī)構(gòu)和工作效能等。
其他的你還可以參考:薩師煊 王珊著 數(shù)據(jù)庫系統(tǒng)概論
暢想未來,但不可忘了過去的教訓(xùn)
我發(fā)現(xiàn)詢問用戶如何看待未來需求變化非常有用。這樣做可以達(dá)到兩個(gè)目的:首先,你可以清楚地了解應(yīng)用設(shè)計(jì)在哪個(gè)地方應(yīng)該更具靈活性以及如何避免性能瓶頸;其次,你知道發(fā)生事先沒有確定的需求變更時(shí)用戶將和你一樣感到吃驚。
一定要記住過去的經(jīng)驗(yàn)教訓(xùn)!我們開發(fā)人員還應(yīng)該通過分享自己的體會和經(jīng)驗(yàn)互相幫助。即使用戶認(rèn)為他們再也不需要什么支持了,我們也應(yīng)該對他們進(jìn)行這方面的教育,我們都曾經(jīng)面臨過這樣的時(shí)刻"當(dāng)初要是這么做了該多好.."。
在物理實(shí)踐之前進(jìn)行邏輯設(shè)計(jì)
在深入物理設(shè)計(jì)之前要先進(jìn)行邏輯設(shè)計(jì)。隨著大量的 CASE 工具不斷涌現(xiàn)出來,你的設(shè)計(jì)也可以達(dá)到相當(dāng)高的邏輯水準(zhǔn),你通常可以從整體上更好地了解數(shù)據(jù)庫設(shè)計(jì)所需要的方方面面。
了解你的業(yè)務(wù)
在你百分百地確定系統(tǒng)從客戶角度滿足其需求之前不要在你的 ER(實(shí)體關(guān)系)模式中加入哪怕一個(gè)數(shù)據(jù)表(怎么,你還沒有模式?那請你參看技巧 9)。了解你的企業(yè)業(yè)務(wù)可以在以后的開發(fā)階段節(jié)約大量的時(shí)間。一旦你明確了業(yè)務(wù)需求,你就可以自己做出許多決策了。
一旦你認(rèn)為你已經(jīng)明確了業(yè)務(wù)內(nèi)容,你最好同客戶進(jìn)行一次系統(tǒng)的交流。采用客戶的術(shù)語并且向他們解釋你所想到的和你所聽到的。同時(shí)還應(yīng)該用可能、將會和必須等詞匯表達(dá)出系統(tǒng)的關(guān)系基數(shù)。這樣你就可以讓你的客戶糾正你自己的理解然后做好下一步的 ER 設(shè)計(jì)。
創(chuàng)建數(shù)據(jù)字典和 ER 圖表
一定要花點(diǎn)時(shí)間創(chuàng)建 ER 圖表和數(shù)據(jù)字典。其中至少應(yīng)該包含每個(gè)字段的數(shù)據(jù)類型和在每個(gè)表內(nèi)的主外鍵。創(chuàng)建 ER 圖表和數(shù)據(jù)字典確實(shí)有點(diǎn)費(fèi)時(shí)但對其他開發(fā)人員要了解整個(gè)設(shè)計(jì)卻是完全必要的。越早創(chuàng)建越能有助于避免今后面臨的可能混亂,從而可以讓任何了解數(shù)據(jù)庫的人都明確如何從數(shù)據(jù)庫中獲得數(shù)據(jù)。
有一份諸如 ER 圖表等最新文檔其重要性如何強(qiáng)調(diào)都不過分,這對表明表之間關(guān)系很有用,而數(shù)據(jù)字典則說明了每個(gè)字段的用途以及任何可能存在的別名。對 SQL 表達(dá)式的文檔化來說這是完全必要的。
創(chuàng)建模式
一張圖表勝過千言萬語:開發(fā)人員不僅要閱讀和實(shí)現(xiàn)它,而且還要用它來幫助自己和用戶對話。模式有助于提高協(xié)作效能,這樣在先期的數(shù)據(jù)庫設(shè)計(jì)中幾乎不可能出現(xiàn)大的問題。模式不必弄的很復(fù)雜;甚至可以簡單到手寫在一張紙上就可以了。只是要保證其上的邏輯關(guān)系今后能產(chǎn)生效益。
從輸入輸出下手
在定義數(shù)據(jù)庫表和字段需求(輸入)時(shí),首先應(yīng)檢查現(xiàn)有的或者已經(jīng)設(shè)計(jì)出的報(bào)表、查詢和視圖(輸出)以決定為了支持這些輸出哪些是必要的表和字段。舉個(gè)簡單的例子:假如客戶需要一個(gè)報(bào)表按照郵政編碼排序、分段和求和,你要保證其中包括了單獨(dú)的郵政編碼字段而不要把郵政編碼糅進(jìn)地址字段里。
報(bào)表技巧
要了解用戶通常是如何報(bào)告數(shù)據(jù)的:批處理還是在線提交報(bào)表?時(shí)間間隔是每天、每周、每月、每個(gè)季度還是每年?如果需要的話還可以考慮創(chuàng)建總結(jié)表。系統(tǒng)生成的主鍵在報(bào)表中很難管理。用戶在具有系統(tǒng)生成主鍵的表內(nèi)用副鍵進(jìn)行檢索往往會返回許多重復(fù)數(shù)據(jù)。這樣的檢索性能比較低而且容易引起混亂。
理解客戶需求
看起來這應(yīng)該是顯而易見的事,但需求就是來自客戶(這里要從內(nèi)部和外部客戶的角度考慮)。不要依賴用戶寫下來的需求,真正的需求在客戶的腦袋里。你要讓客戶解釋其需求,而且隨著開發(fā)的繼續(xù),還要經(jīng)常詢問客戶保證其需求仍然在開發(fā)的目的之中。一個(gè)不變的真理是:"只有我看見了我才知道我想要的是什么"必然會導(dǎo)致大量的返工,因?yàn)閿?shù)據(jù)庫沒有達(dá)到客戶從來沒有寫下來的需求標(biāo)準(zhǔn)。而更糟的是你對他們需求的解釋只屬于你自己,而且可能是完全錯(cuò)誤的。
第 2 部分 - 設(shè)計(jì)表和字段
檢查各種變化
我在設(shè)計(jì)數(shù)據(jù)庫的時(shí)候會考慮到哪些數(shù)據(jù)字段將來可能會發(fā)生變更。比方說,姓氏就是如此(注意是西方人的姓氏,比如女性結(jié)婚后從夫姓等)。所以,在建立系統(tǒng)存儲客戶信息時(shí),我傾向于在單獨(dú)的一個(gè)數(shù)據(jù)表里存儲姓氏字段,而且還附加起始日和終止日等字段,這樣就可以跟蹤這一數(shù)據(jù)條目的變化。
采用有意義的字段名
有一回我參加開發(fā)過一個(gè)項(xiàng)目,其中有從其他程序員那里繼承的程序,那個(gè)程序員喜歡用屏幕上顯示數(shù)據(jù)指示用語命名字段,這也不賴,但不幸的是,她還喜歡用一些奇怪的命名法,其命名采用了匈牙利命名和控制序號的組合形式,比如 cbo1、txt2、txt2_b 等等。
除非你在使用只面向你的縮寫字段名的系統(tǒng),否則請盡可能地把字段描述的清楚些。當(dāng)然,也別做過頭了,比如 Customer_Shipping_Address_Street_Line_1,雖然很富有說明性,但沒人愿意鍵入這么長的名字,具體尺度就在你的把握中。
采用前綴命名
如果多個(gè)表里有好多同一類型的字段(比如 FirstName),你不妨用特定表的前綴(比如 CusLastName)來幫助你標(biāo)識字段。
時(shí)效性數(shù)據(jù)應(yīng)包括"最近更新日期/時(shí)間"字段。時(shí)間標(biāo)記對查找數(shù)據(jù)問題的原因、按日期重新處理/重載數(shù)據(jù)和清除舊數(shù)據(jù)特別有用。
標(biāo)準(zhǔn)化和數(shù)據(jù)驅(qū)動
數(shù)據(jù)的標(biāo)準(zhǔn)化不僅方便了自己而且也方便了其他人。比方說,假如你的用戶界面要訪問外部數(shù)據(jù)源(文件、XML 文檔、其他數(shù)據(jù)庫等),你不妨把相應(yīng)的連接和路徑信息存儲在用戶界面支持表里。還有,如果用戶界面執(zhí)行工作流之類的任務(wù)(發(fā)送郵件、打印信箋、修改記錄狀態(tài)等),那么產(chǎn)生工作流的數(shù)據(jù)也可以存放在數(shù)據(jù)庫里。預(yù)先安排總需要付出努力,但如果這些過程采用數(shù)據(jù)驅(qū)動而非硬編碼的方式,那么策略變更和維護(hù)都會方便得多。事實(shí)上,如果過程是數(shù)據(jù)驅(qū)動的,你就可以把相當(dāng)大的責(zé)任推給用戶,由用戶來維護(hù)自己的工作流過程。
標(biāo)準(zhǔn)化不能過頭
對那些不熟悉標(biāo)準(zhǔn)化一詞(normalization)的人而言,標(biāo)準(zhǔn)化可以保證表內(nèi)的字段都是最基礎(chǔ)的要素,而這一措施有助于消除數(shù)據(jù)庫中的數(shù)據(jù)冗余。標(biāo)準(zhǔn)化有好幾種形式,但 Third Normal Form(3NF)通常被認(rèn)為在性能、擴(kuò)展性和數(shù)據(jù)完整性方面達(dá)到了最好平衡。簡單來說,3NF 規(guī)定:
* 表內(nèi)的每一個(gè)值都只能被表達(dá)一次。
* 表內(nèi)的每一行都應(yīng)該被唯一的標(biāo)識(有唯一鍵)。
* 表內(nèi)不應(yīng)該存儲依賴于其他鍵的非鍵信息。
遵守 3NF 標(biāo)準(zhǔn)的數(shù)據(jù)庫具有以下特點(diǎn):有一組表專門存放通過鍵連接起來的關(guān)聯(lián)數(shù)據(jù)。比方說,某個(gè)存放客戶及其有關(guān)定單的 3NF 數(shù)據(jù)庫就可能有兩個(gè)表:Customer 和 Order。Order 表不包含定單關(guān)聯(lián)客戶的任何信息,但表內(nèi)會存放一個(gè)鍵值,該鍵指向 Customer 表里包含該客戶信息的那一行。
更高層次的標(biāo)準(zhǔn)化也有,但更標(biāo)準(zhǔn)是否就一定更好呢?答案是不一定。事實(shí)上,對某些項(xiàng)目來說,甚至就連 3NF 都可能給數(shù)據(jù)庫引入太高的復(fù)雜性。
為了效率的緣故,對表不進(jìn)行標(biāo)準(zhǔn)化有時(shí)也是必要的,這樣的例子很多。曾經(jīng)有個(gè)開發(fā)餐飲分析軟件的活就是用非標(biāo)準(zhǔn)化表把查詢時(shí)間從平均 40 秒降低到了兩秒左右。雖然我不得不這么做,但我絕不把數(shù)據(jù)表的非標(biāo)準(zhǔn)化當(dāng)作當(dāng)然的設(shè)計(jì)理念。而具體的操作不過是一種派生。所以如果表出了問題重新產(chǎn)生非標(biāo)準(zhǔn)化的表是完全可能的。
不活躍或者不采用的指示符
增加一個(gè)字段表示所在記錄是否在業(yè)務(wù)中不再活躍挺有用的。不管是客戶、員工還是其他什么人,這樣做都能有助于再運(yùn)行查詢的時(shí)候過濾活躍或者不活躍狀態(tài)。同時(shí)還消除了新用戶在采用數(shù)據(jù)時(shí)所面臨的一些問題,比如,某些記錄可能不再為他們所用,再刪除的時(shí)候可以起到一定的防范作用。
使用角色實(shí)體定義屬于某類別的列[字段]
在需要對屬于特定類別或者具有特定角色的事物做定義時(shí),可以用角色實(shí)體來創(chuàng)建特定的時(shí)間關(guān)聯(lián)關(guān)系,從而可以實(shí)現(xiàn)自我文檔化。
這里的含義不是讓 PERSON 實(shí)體帶有 Title 字段,而是說,為什么不用 PERSON 實(shí)體和 PERSON_TYPE 實(shí)體來描述人員呢?比方說,當(dāng) John Smith, Engineer 提升為 John Smith, Director 乃至最后爬到 John Smith, CIO 的高位,而所有你要做的不過是改變兩個(gè)表 PERSON 和 PERSON_TYPE 之間關(guān)系的鍵值,同時(shí)增加一個(gè)日期/時(shí)間字段來知道變化是何時(shí)發(fā)生的。這樣,你的 PERSON_TYPE 表就包含了所有 PERSON 的可能類型,比如 Associate、Engineer、Director、CIO 或者 CEO 等。
還有個(gè)替代辦法就是改變 PERSON 記錄來反映新頭銜的變化,不過這樣一來在時(shí)間上無法跟蹤個(gè)人所處位置的具體時(shí)間。
采用常用實(shí)體命名機(jī)構(gòu)數(shù)據(jù)
組織數(shù)據(jù)的最簡單辦法就是采用常用名字,比如:PERSON、ORGANIZATION、ADDRESS 和 PHONE 等等。當(dāng)你把這些常用的一般名字組合起來或者創(chuàng)建特定的相應(yīng)副實(shí)體時(shí),你就得到了自己用的特殊版本。開始的時(shí)候采用一般術(shù)語的主要原因在于所有的具體用戶都能對抽象事物具體化。
有了這些抽象表示,你就可以在第 2 級標(biāo)識中采用自己的特殊名稱,比如,PERSON 可能是 Employee、Spouse、Patient、Client、Customer、Vendor 或者 Teacher 等。同樣的,ORGANIZATION 也可能是 MyCompany、MyDepartment、Competitor、Hospital、Warehouse、Government 等。最后 ADDRESS 可以具體為 Site、Location、Home、Work、Client、Vendor、Corporate 和 FieldOffice 等。
采用一般抽象術(shù)語來標(biāo)識"事物"的類別可以讓你在關(guān)聯(lián)數(shù)據(jù)以滿足業(yè)務(wù)要求方面獲得巨大的靈活性,同時(shí)這樣做還可以顯著降低數(shù)據(jù)存儲所需的冗余量。
用戶來自世界各地
在設(shè)計(jì)用到網(wǎng)絡(luò)或者具有其他國際特性的數(shù)據(jù)庫時(shí),一定要記住大多數(shù)國家都有不同的字段格式,比如郵政編碼等,有些國家,比如新西蘭就沒有郵政編碼一說。
數(shù)據(jù)重復(fù)需要采用分立的數(shù)據(jù)表
如果你發(fā)現(xiàn)自己在重復(fù)輸入數(shù)據(jù),請創(chuàng)建新表和新的關(guān)系。
每個(gè)表中都應(yīng)該添加的 3 個(gè)有用的字段
* dRecordCreationDate,在 VB 下默認(rèn)是 Now(),而在 SQL Server 下默認(rèn)為 GETDATE()
* sRecordCreator,在 SQL Server 下默認(rèn)為 NOT NULL DEFAULT USER
* nRecordVersion,記錄的版本標(biāo)記;有助于準(zhǔn)確說明記錄中出現(xiàn) null 數(shù)據(jù)或者丟失數(shù)據(jù)的原因
對地址和電話采用多個(gè)字段
描述街道地址就短短一行記錄是不夠的。Address_Line1、Address_Line2 和 Address_Line3 可以提供更大的靈活性。還有,電話號碼和郵件地址最好擁有自己的數(shù)據(jù)表,其間具有自身的類型和標(biāo)記類別。
過分標(biāo)準(zhǔn)化可要小心,這樣做可能會導(dǎo)致性能上出現(xiàn)問題。雖然地址和電話表分離通??梢赃_(dá)到最佳狀態(tài),但是如果需要經(jīng)常訪問這類信息,或許在其父表中存放"首選"信息(比如 Customer 等)更為妥當(dāng)些。非標(biāo)準(zhǔn)化和加速訪問之間的妥協(xié)是有一定意義的。
使用多個(gè)名稱字段
我覺得很吃驚,許多人在數(shù)據(jù)庫里就給 name 留一個(gè)字段。我覺得只有剛?cè)腴T的開發(fā)人員才會這么做,但實(shí)際上網(wǎng)上這種做法非常普遍。我建議應(yīng)該把姓氏和名字當(dāng)作兩個(gè)字段來處理,然后在查詢的時(shí)候再把他們組合起來。
我最常用的是在同一表中創(chuàng)建一個(gè)計(jì)算列[字段],通過它可以自動地連接標(biāo)準(zhǔn)化后的字段,這樣數(shù)據(jù)變動的時(shí)候它也跟著變。不過,這樣做在采用建模軟件時(shí)得很機(jī)靈才行??傊?,采用連接字段的方式可以有效的隔離用戶應(yīng)用和開發(fā)人員界面。
提防大小寫混用的對象名和特殊字符
過去最令我惱火的事情之一就是數(shù)據(jù)庫里有大小寫混用的對象名,比如 CustomerData。這一問題從 Access 到 Oracle 數(shù)據(jù)庫都存在。我不喜歡采用這種大小寫混用的對象命名方法,結(jié)果還不得不手工修改名字。想想看,這種數(shù)據(jù)庫/應(yīng)用程序能混到采用更強(qiáng)大數(shù)據(jù)庫的那一天嗎?采用全部大寫而且包含下劃符的名字具有更好的可讀性(CUSTOMER_DATA),絕對不要在對象名的字符之間留空格。
小心保留詞
要保證你的字段名沒有和保留詞、數(shù)據(jù)庫系統(tǒng)或者常用訪問方法沖突,比如,最近我編寫的一個(gè) ODBC 連接程序里有個(gè)表,其中就用了 DESC 作為說明字段名。后果可想而知!DESC 是 DESCENDING 縮寫后的保留詞。表里的一個(gè) SELECT * 語句倒是能用,但我得到的卻是一大堆毫無用處的信息。
保持字段名和類型的一致性
在命名字段并為其指定數(shù)據(jù)類型的時(shí)候一定要保證一致性。假如字段在某個(gè)表中叫做"agreement_number",你就別在另一個(gè)表里把名字改成"ref1"。假如數(shù)據(jù)類型在一個(gè)表里是整數(shù),那在另一個(gè)表里可就別變成字符型了。記住,你干完自己的活了,其他人還要用你的數(shù)據(jù)庫呢。
仔細(xì)選擇數(shù)字類型
在 SQL 中使用 smallint 和 tinyint 類型要特別小心,比如,假如你想看看月銷售總額,你的總額字段類型是 smallint,那么,如果總額超過了 $32,767 你就不能進(jìn)行計(jì)算操作了。
刪除標(biāo)記
在表中包含一個(gè)"刪除標(biāo)記"字段,這樣就可以把行標(biāo)記為刪除。在關(guān)系數(shù)據(jù)庫里不要單獨(dú)刪除某一行;最好采用清除數(shù)據(jù)程序而且要仔細(xì)維護(hù)索引整體性。
避免使用觸發(fā)器觸發(fā)器的功能通??梢杂闷渌绞綄?shí)現(xiàn)。在調(diào)試程序時(shí)觸發(fā)器可能成為干擾。假如你確實(shí)需要采用觸發(fā)器,你最好集中對它文檔化。
包含版本機(jī)制
建議你在數(shù)據(jù)庫中引入版本控制機(jī)制來確定使用中的數(shù)據(jù)庫的版本。無論如何你都要實(shí)現(xiàn)這一要求。時(shí)間一長,用戶的需求總是會改變的。最終可能會要求修改數(shù)據(jù)庫結(jié)構(gòu)。雖然你可以通過檢查新字段或者索引來確定數(shù)據(jù)庫結(jié)構(gòu)的版本,但我發(fā)現(xiàn)把版本信息直接存放到數(shù)據(jù)庫中不更為方便嗎?。
給文本字段留足余量
ID 類型的文本字段,比如客戶 ID 或定單號等等都應(yīng)該設(shè)置得比一般想象更大,因?yàn)闀r(shí)間不長你多半就會因?yàn)橐砑宇~外的字符而難堪不已。比方說,假設(shè)你的客戶 ID 為 10 位數(shù)長。那你應(yīng)該把數(shù)據(jù)庫表字段的長度設(shè)為 12 或者 13 個(gè)字符長。這算浪費(fèi)空間嗎?是有一點(diǎn),但也沒你想象的那么多:一個(gè)字段加長 3 個(gè)字符在有 1 百萬條記錄,再加上一點(diǎn)索引的情況下才不過讓整個(gè)數(shù)據(jù)庫多占據(jù) 3MB 的空間。但這額外占據(jù)的空間卻無需將來重構(gòu)整個(gè)數(shù)據(jù)庫就可以實(shí)現(xiàn)數(shù)據(jù)庫規(guī)模的增長了。身份證的號碼從 15 位變成 18 位就是最好和最慘痛的例子。
列[字段]命名技巧
我們發(fā)現(xiàn),假如你給每個(gè)表的列[字段]名都采用統(tǒng)一的前綴,那么在編寫 SQL 表達(dá)式的時(shí)候會得到大大的簡化。這樣做也確實(shí)有缺點(diǎn),比如破壞了自動表連接工具的作用,后者把公共列[字段]名同某些數(shù)據(jù)庫聯(lián)系起來,不過就連這些工具有時(shí)不也連接錯(cuò)誤嘛。舉個(gè)簡單的例子,假設(shè)有兩個(gè)表:
Customer 和 Order。Customer 表的前綴是 cu_,所以該表內(nèi)的子段名如下:cu_name_id、cu_surname、cu_initials 和cu_address 等。Order 表的前綴是 or_,所以子段名是:
or_order_id、or_cust_name_id、or_quantity 和 or_deion 等。
這樣從數(shù)據(jù)庫中選出全部數(shù)據(jù)的 SQL 語句可以寫成如下所示:
Select * From Customer, Order Where cu_surname = "MYNAME" ;
and cu_name_id = or_cust_name_id and or_quantity = 1
在沒有這些前綴的情況下則寫成這個(gè)樣子(用別名來區(qū)分):
Select * From Customer, Order Where Customer.surname = "MYNAME" ;
and Customer.name_id = Order.cust_name_id and Order.quantity = 1
第 1 個(gè) SQL 語句沒少鍵入多少字符。但如果查詢涉及到 5 個(gè)表乃至更多的列[字段]你就知道這個(gè)技巧多有用了。
021yin.com