【導讀】一個(gè)好的數據庫產(chǎn)品不等于就有一個(gè)好的應用系統,如果不能設計一個(gè)合理的數據庫模型,不僅會(huì )增加客戶(hù)端和服務(wù)器段程序的編程和維護的難度,而且將會(huì )影響系統實(shí)際運行的性能。
一個(gè)好的數據庫產(chǎn)品不等于就有一個(gè)好的應用系統,如果不能設計一個(gè)合理的數據庫模型,不僅會(huì )增加客戶(hù)端和服務(wù)器段程序的編程和維護的難度,而且將會(huì )影響系統實(shí)際運行的性能。一般來(lái)講,在一個(gè)MIS系統分析、設計、測試和試運行階段,因為數據量較小,設計人員和測試人員往往只注意到功能的實(shí)現,而很難注意到性能的薄弱之處,等到系統投入實(shí)際運行一段時(shí)間后,才發(fā)現系統的性能在降低,這時(shí)再來(lái)考慮提高系統性能則要花費更多的人力物力,而整個(gè)系統也不可避免的形成了一個(gè)打補丁工程。筆者依據多年來(lái)設計和使用數據庫的經(jīng)驗,提出以下一些設計準則,供同仁們參考。命名的規范---- 不同的數據庫產(chǎn)品對對象的命名有不同的要求,因此,數據庫中的各種對象的命名、后臺程序的代碼編寫(xiě)應采用大小寫(xiě)敏感的形式,各種對象命名長(cháng)度不要超過(guò)30個(gè)字符,這樣便于應用系統適應不同的數據庫。游標(Cursor)的慎用---- 游標提供了對特定集合中逐行掃描的手段,一般使用游標逐行遍歷數據,根據取出的數據不同條件進(jìn)行不同的操作。尤其對多表和大表定義的游標(大的數據集合)循環(huán)很容易使程序進(jìn)入一個(gè)漫長(cháng)的等特甚至死機,筆者在某市《住房公積金管理系統》進(jìn)行日終帳戶(hù)滾積數計息處理時(shí),對一個(gè)10萬(wàn)個(gè)帳戶(hù)的游標處理導致程序進(jìn)入了一個(gè)無(wú)限期的等特(后經(jīng)測算需48個(gè)小時(shí)才能完成)(硬件環(huán)境:Alpha/4000 128Mram ,Sco Unix,Sybase 11.0),后根據不同的條件改成用不同的UPDATE語(yǔ)句得以在二十分鐘之內完成。示例如下:Declare Mycursor cursor for select count_no from COUNTOpen MycursorFetch Mycursor into @vcount_noWhile (@@sqlstatus=0)BeginIf @vcount_no=’’ 條件1操作1If @vcount_no=’’ 條件2操作2。。。Fetch Mycursor into @vcount_noEnd。。。。。。改為Update COUNT set 操作1 for 條件1Update COUNT set 操作2 for 條件2。。。。。。---- 在有些場(chǎng)合,有時(shí)也非得使用游標,此時(shí)也可考慮將符合條件的數據行轉入臨時(shí)表中,再對臨時(shí)表定義游標進(jìn)行操作,可時(shí)性能得到明顯提高。筆者在某地市〈電信收費系統〉數據庫后臺程序設計中,對一個(gè)表(3萬(wàn)行中符合條件的30多行數據)進(jìn)行游標操作(硬件環(huán)境:PC服務(wù)器,PII266 64Mram ,NT4.0 Ms Sqlserver 6.5)。 示例如下:Create #tmp /* 定義臨時(shí)表 */( 字段1字段2。。。)Insert into #tmp select * from TOTAL where條件 /* TOTAL中3萬(wàn)行 符合條件只有幾十行 */Declare Mycursor cursor for select * from #tmp/*對臨時(shí)表定義游標*/。。。索引(Index)的使用原則---- 創(chuàng )建索引一般有以下兩個(gè)目的:維護被索引列的唯一性和提供快速訪(fǎng)問(wèn)表中數據的策略。大型數據庫有兩種索引即簇索引和非簇索引,一個(gè)沒(méi)有簇索引的表是按堆結構存儲數據,所有的數據均添加在表的尾部,而建立了簇索引的表,其數據在物理上會(huì )按照簇索引鍵的順序存儲,一個(gè)表只允許有一個(gè)簇索引,因此,根據B樹(shù)結構,可以理解添加任何一種索引均能提高按索引列查詢(xún)的速度,但會(huì )降低插入、更新、刪除操作的性能,尤其是當填充因子(Fill Factor)較大時(shí)。所以對索引較多的表進(jìn)行頻繁的插入、更新、刪除操作,建表和索引時(shí)因設置較小的填充因子,以便在各數據頁(yè)中留下較多的自由空間,減少頁(yè)分割及重新組織的工作。數據的一致性和完整性---- 為了保證數據庫的一致性和完整性,設計人員往往會(huì )設計過(guò)多的表間關(guān)聯(lián)(Relation),盡可能的降低數據的冗余。表間關(guān)聯(lián)是一種強制性措施,建立后,對父表(Parent Table)和子表(Child Table)的插入、更新、刪除操作均要占用系統的開(kāi)銷(xiāo),另外,最好不要用Identify 屬性字段作為主鍵與子表關(guān)聯(lián)。如果數據冗余低,數據的完整性容易得到保證,但增加了表間連接查詢(xún)的操作,為了提高系統的響應時(shí)間,合理的數據冗余也是必要的。使用規則(Rule)和約束(Check)來(lái)防止系統操作人員誤輸入造成數據的錯誤是設計人員的另一種常用手段,但是,不必要的規則和約束也會(huì )占用系統的不必要開(kāi)銷(xiāo),需要注意的是,約束對數據的有效性驗證要比規則快。所有這些,設計人員在設計階段應根據系統操作的類(lèi)型、頻度加以均衡考慮。事務(wù)的陷阱---- 事務(wù)是在一次性完成的一組操作。雖然這些操作是單個(gè)的操作,SQL Server能夠保證這組操作要么全部都完成,要么一點(diǎn)都不做。正是大型數據庫的這一特性,使得數據的完整性得到了極大的保證。---- 眾所周知,SQL Server為每個(gè)獨立的SQL語(yǔ)句都提供了隱含的事務(wù)控制,使得每個(gè)DML的數據操作得以完整提交或回滾,但是SQL Server還提供了顯式事務(wù)控制語(yǔ)句---- BEGIN TRANSACTION 開(kāi)始一個(gè)事務(wù)---- COMMIT TRANSACTION 提交一個(gè)事務(wù)---- ROLLBACK TRANSACTION 回滾一個(gè)事務(wù)---- 事務(wù)可以嵌套,可以通過(guò)全局變量@@trancount檢索到連接的事務(wù)處理嵌套層次。需要加以特別注意并且極容易使編程人員犯錯誤的是,每個(gè)顯示或隱含的事物開(kāi)始都使得該變量加1,每個(gè)事務(wù)的提交使該變量減1,每個(gè)事務(wù)的回滾都會(huì )使得該變量置0,而只有當該變量為0時(shí)的事務(wù)提交(最后一個(gè)提交語(yǔ)句時(shí)),這時(shí)才把物理數據寫(xiě)入磁盤(pán)。數據庫性能調整---- 在計算機硬件配置和網(wǎng)絡(luò )設計確定的情況下,影響到應用系統性能的因素不外乎為數據庫性能和客戶(hù)端程序設計。而大多數數據庫設計員采用兩步法進(jìn)行數據庫設計:首先進(jìn)行邏輯設計,而后進(jìn)行物理設計。數據庫邏輯設計去除了所有冗余數據,提高了數據吞吐速度,保證了數據的完整性,清楚地表達數據元素之間的關(guān)系。而對于多表之間的關(guān)聯(lián)查詢(xún)(尤其是大數據表)時(shí),其性能將會(huì )降低,同時(shí)也提高了客 戶(hù)端程序的編程難度,因此,物理設計需折衷考慮,根據業(yè)務(wù)規則,確定對關(guān)聯(lián)表的數據量大小、數據項的訪(fǎng)問(wèn)頻度,對此類(lèi)數據表頻繁的關(guān)聯(lián)查詢(xún)應適當提高數據冗余設計。數據類(lèi)型的選擇---- 數據類(lèi)型的合理選擇對于數據庫的性能和操作具有很大的影響,有關(guān)這方面的書(shū)籍也有不少的闡述,這里主要介紹幾點(diǎn)經(jīng)驗。Identify字段不要作為表的主鍵與其它表關(guān)聯(lián),這將會(huì )影響到該表的數據遷移。Text 和Image字段屬指針型數據,主要用來(lái)存放二進(jìn)制大型對象(BLOB)。這類(lèi)數據的操作相比其它數據類(lèi)型較慢,因此要避開(kāi)使用。日期型字段的優(yōu)點(diǎn)是有眾多的日期函數支持,因此,在日期的大小比較、加減操作上非常簡(jiǎn)單。但是,在按照日期作為條件的查詢(xún)操作也要用函數,相比其它數據類(lèi)型速度上就慢許多,因為用函數作為查詢(xún)的條件時(shí),服務(wù)器無(wú)法用先進(jìn)的性能策略來(lái)優(yōu)化查詢(xún)而只能進(jìn)行表掃描遍歷每行。---- 例如:要從DATA_TAB1中(其中有一個(gè)名為DATE的日期字段)查詢(xún)1998年的所有記錄。---- Select * from DATA_TAB1 where datepart(yy,DATE)=1998--
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。