閑談Oracle應(yīng)用數(shù)據(jù)庫系統(tǒng)設(shè)計(jì)與開發(fā)簡(jiǎn)介
Oracle是公認(rèn)安全性最高的數(shù)據(jù)庫系統(tǒng)。企業(yè)級(jí)的Oracle數(shù)據(jù)庫應(yīng)用系統(tǒng)包括系統(tǒng)硬件、操作系統(tǒng)、網(wǎng)絡(luò)層、DBMS(數(shù)據(jù)庫管理系統(tǒng))、應(yīng)用程序與數(shù)據(jù),各部分之間是互相依賴的,對(duì)每個(gè)部分都必須進(jìn)行合理的配置、設(shè)計(jì)和優(yōu)化才能實(shí)現(xiàn)高性能的數(shù)據(jù)庫系統(tǒng)。本文討論筆者使用Oracle開發(fā)局域網(wǎng)中、小型數(shù)據(jù)庫應(yīng)用中,系統(tǒng)硬件的選擇與使用、應(yīng)用數(shù)據(jù)庫系統(tǒng)設(shè)計(jì)與開發(fā)方面的一些心得和建議。Oracle數(shù)據(jù)庫應(yīng)用系統(tǒng)包含應(yīng)用數(shù)據(jù)庫和應(yīng)用兩方面的內(nèi)容,應(yīng)用數(shù)據(jù)庫就是生產(chǎn)數(shù)據(jù)庫,與系統(tǒng)數(shù)據(jù)庫相對(duì)。
系統(tǒng)硬件的選擇與使用與數(shù)據(jù)庫系統(tǒng)密切相關(guān)的硬件主要有CPU、內(nèi)存、集群、存儲(chǔ)設(shè)備等,這里不對(duì)集群進(jìn)行討論。
1、CPU
CPU的數(shù)目和速度直接影響數(shù)據(jù)庫操作的速度,Oracle數(shù)據(jù)庫提供并行查詢選項(xiàng),允許SQL操作以協(xié)同方式在多個(gè)CPU上執(zhí)行,可以很大程度的發(fā)揮多CPU的性能。為系統(tǒng)添加CPU前,首先要對(duì)應(yīng)用程序的SQL代碼做優(yōu)化,提高應(yīng)用程序的效率,質(zhì)量低劣的應(yīng)用可能會(huì)引起CPU資源的無謂的消耗;其次,要了解操作系統(tǒng)對(duì)CPU數(shù)目的限制及系統(tǒng)的可擴(kuò)展性。在系統(tǒng)CPU資源已定的情況下,要對(duì)各類應(yīng)用進(jìn)行分析,在保證關(guān)鍵應(yīng)用正常運(yùn)行的前提下,盡可能將大量占用CPU資源的應(yīng)用放在系統(tǒng)相對(duì)空閑的時(shí)候進(jìn)行。良好的工作調(diào)度可以有效減少對(duì)CPU的競(jìng)爭(zhēng)使用,加快系統(tǒng)的響應(yīng)時(shí)間。
2、內(nèi)存
數(shù)據(jù)庫系統(tǒng)中,應(yīng)保證有足夠大的內(nèi)存。在UNIX系統(tǒng)中,如果系統(tǒng)的物理內(nèi)存小于1GB,可將交換區(qū)的大小設(shè)為內(nèi)存的4倍,否則,可設(shè)為內(nèi)存的2倍,交換區(qū)要放在磁盤速度最快的硬盤上。Oracle 的SGA區(qū)大小直接關(guān)系到數(shù)據(jù)庫操作的性能,一般來說,SGA區(qū)的大小可設(shè)為系統(tǒng)可用內(nèi)存的55%到57%,SGA區(qū)過多占用系統(tǒng)內(nèi)存反而會(huì)降低性能。在應(yīng)用系統(tǒng)運(yùn)行中,應(yīng)定期監(jiān)測(cè)系統(tǒng)的內(nèi)存使用情況,對(duì)關(guān)鍵應(yīng)用進(jìn)行分析,根據(jù)應(yīng)用適時(shí)調(diào)整SGA區(qū)各部分的大小。Oracle9i可在不重新啟動(dòng)數(shù)據(jù)庫的情況下修改SGA區(qū)的參數(shù),實(shí)時(shí)改變SGA區(qū)的大小。
3、存儲(chǔ)設(shè)備
在網(wǎng)絡(luò)時(shí)代,信息資源的積累和廣泛應(yīng)用對(duì)數(shù)據(jù)存儲(chǔ)技術(shù)的發(fā)展提出了更大的挑戰(zhàn),數(shù)據(jù)存儲(chǔ)模式從傳統(tǒng)的總線連接模式進(jìn)入了網(wǎng)絡(luò)存儲(chǔ)模式。但存儲(chǔ)設(shè)備依然是硬盤、磁帶(帶庫)、磁盤陣列,在中、小型數(shù)據(jù)庫應(yīng)用中傳統(tǒng)存儲(chǔ)模式仍占主導(dǎo)地位。
磁盤I/O是數(shù)據(jù)庫操作的瓶頸之一,磁盤的合理選擇和使用在數(shù)據(jù)庫系統(tǒng)中顯得尤為重要。在最初做數(shù)據(jù)庫系統(tǒng)規(guī)劃時(shí),應(yīng)充分考慮到系統(tǒng)的容量和預(yù)期的增長,盡可能為以后的擴(kuò)展留足空間。在硬盤和磁盤陣列的選擇與使用中,應(yīng)注意以下幾點(diǎn):
◆選擇支持熱插拔功能的硬盤,這樣在出現(xiàn)硬盤Oracle 平臺(tái)應(yīng)用數(shù)據(jù)庫系統(tǒng)的設(shè)計(jì)與開發(fā)失敗時(shí),可以在系統(tǒng)正常運(yùn)行的情況下更換硬盤;
◆不要選擇太大的硬盤,切記對(duì)Oracle 應(yīng)用程序,1~4GB大小的硬盤是比較合適的,最好購買大量的中小型硬盤,這樣在配置RAID時(shí)可提供更大的靈活性;
◆如果選用了磁盤陣列,對(duì)于Oracle數(shù)據(jù)庫應(yīng)用,如果經(jīng)費(fèi)能夠支持,RAID 0+1是最佳的配置方法。在RAID 5中,讀操作性能得到了一定的改善,但寫性能損失很大,如果某個(gè)硬盤失敗,硬盤重建的工作量非常大,RAID 5 適用于DSS(決策支持系統(tǒng))應(yīng)用,對(duì)OLTP(聯(lián)機(jī)事物處理)應(yīng)用不太合適;
·在實(shí)現(xiàn)RAID時(shí),要正確地選擇分條的大小,決定分條大小的三個(gè)主要因素是:應(yīng)用程序的特性(DSS、OLTP、批處理)、操作系統(tǒng)與數(shù)據(jù)庫的數(shù)據(jù)塊大小、磁盤陣列中的硬盤數(shù)目。數(shù)據(jù)庫的數(shù)據(jù)塊大小應(yīng)是操作系統(tǒng)數(shù)據(jù)塊大小的整數(shù)倍,同樣分條大小也必須是操作系統(tǒng)數(shù)據(jù)塊大小的整數(shù)倍。如果使用裸設(shè)備,分條大小應(yīng)是操作系統(tǒng)物理數(shù)據(jù)塊的大小。分條可按照水平方向進(jìn)行,也可按照垂直方向進(jìn)行。水平分條跨越每個(gè)硬盤控制器進(jìn)行,垂直分條跨越整個(gè)硬盤集合進(jìn)行,分條集合中的成員數(shù)應(yīng)不大于硬盤控制器數(shù)。OLTP應(yīng)用程序,數(shù)據(jù)訪問的數(shù)據(jù)量不大,一般可選擇32KB 或64KB 的分條大小,而DSS應(yīng)用程序訪問的數(shù)據(jù)量大,可考慮使用64KB、128KB或256KB的分條大小。
Oracle數(shù)據(jù)庫應(yīng)用的設(shè)計(jì)與開發(fā)
Oracle數(shù)據(jù)庫應(yīng)用軟件安裝和配置完成后,就進(jìn)入了應(yīng)用數(shù)據(jù)庫的設(shè)計(jì)階段,應(yīng)用數(shù)據(jù)庫設(shè)計(jì)包括邏輯設(shè)計(jì)與物理設(shè)計(jì)。合理的邏輯設(shè)計(jì)會(huì)大大提高數(shù)據(jù)庫的性能,增強(qiáng)數(shù)據(jù)庫的可維護(hù)性。在設(shè)計(jì)中根據(jù)應(yīng)用,抽象出實(shí)體關(guān)系模型,將實(shí)體關(guān)系圖映射為標(biāo)準(zhǔn)化(數(shù)據(jù)完整、與應(yīng)用無關(guān)、存儲(chǔ)優(yōu)化)的關(guān)系模型(數(shù)據(jù)庫對(duì)象),當(dāng)前有一些輔助工具(Oracle Designer等)來實(shí)現(xiàn)實(shí)體關(guān)系圖到SQL代碼的映射;數(shù)據(jù)庫的物理設(shè)計(jì)就是數(shù)據(jù)庫對(duì)象的存儲(chǔ)設(shè)計(jì),即如何為數(shù)據(jù)庫對(duì)象分配存儲(chǔ)空間。
在進(jìn)行數(shù)據(jù)庫對(duì)象的設(shè)計(jì)前,數(shù)據(jù)庫的管理和開發(fā)人員對(duì)應(yīng)用和應(yīng)用的數(shù)據(jù)及其應(yīng)用關(guān)系要有一個(gè)詳盡的理解,根據(jù)應(yīng)用進(jìn)行數(shù)據(jù)庫對(duì)象的規(guī)劃和設(shè)計(jì),大概包含以下幾個(gè)方面:
◆確定需建立的數(shù)據(jù)庫用戶,明確用戶的系統(tǒng)權(quán)限和表空間限額,為用戶設(shè)計(jì)資源限制profile;
◆確定應(yīng)用數(shù)據(jù)應(yīng)分多少個(gè)表進(jìn)行設(shè)計(jì),各表分別屬于的用戶,各用戶對(duì)各個(gè)表的操作權(quán)限;
◆明確各表的結(jié)構(gòu),確定表的主鍵及約束;
◆明確哪些表是應(yīng)用運(yùn)行的關(guān)鍵表,哪些是事務(wù)表;
◆分析哪些表是主表,哪些表是從表,確定表和表之間的外鍵約束,選擇合適的表作為表連接的驅(qū)動(dòng)表;
◆根據(jù)應(yīng)用,確定在哪些表上對(duì)哪些列建立合適的索引;
◆根據(jù)表和索引的設(shè)計(jì),確定要?jiǎng)?chuàng)建的表空間和回滾段,為表空間和回滾段選擇合適的磁盤,盡可能創(chuàng)建本地管理的表空間,減少數(shù)據(jù)庫空間管理方面的工作;
◆明確需要編寫的觸發(fā)器及過程;
◆為數(shù)據(jù)庫對(duì)象選擇備份和恢復(fù)策略。
在數(shù)據(jù)庫設(shè)計(jì)階段,有時(shí)未必能完全確定合適的數(shù)據(jù)庫對(duì)象的特征,應(yīng)用設(shè)計(jì)和開發(fā)中還可能發(fā)現(xiàn)不合適的地方,需要回過頭來進(jìn)行調(diào)整和修改。但設(shè)計(jì)階段的工作越細(xì)致,出現(xiàn)問題的可能性就越小,工作的效率就越高。#p#
創(chuàng)建數(shù)據(jù)庫對(duì)象時(shí),要根據(jù)數(shù)據(jù)庫對(duì)象的特點(diǎn),結(jié)合存儲(chǔ)設(shè)備的大小、數(shù)量及速度等,對(duì)數(shù)據(jù)庫對(duì)象分類進(jìn)行存儲(chǔ),最大限度地消除或減少資源競(jìng)爭(zhēng)。在數(shù)據(jù)庫對(duì)象創(chuàng)建時(shí)主要應(yīng)遵循以下原則:
◆應(yīng)用數(shù)據(jù)應(yīng)放在單獨(dú)的表空間,不要將應(yīng)用數(shù)據(jù)放在系統(tǒng)表空間,為防止無意的使用系統(tǒng)表空間,將應(yīng)用用戶的系統(tǒng)表空間限額設(shè)為0。
◆索引和表應(yīng)放在位于不同硬盤上的不同的表空間,這樣會(huì)提高數(shù)據(jù)庫操作的速度。
◆需要同時(shí)被訪問的表要分開存放,利于并發(fā)訪問的實(shí)施。
◆如果磁盤數(shù)量有限,可把不常聯(lián)合訪問的表放在相同的磁盤上。
◆預(yù)分配的原則。創(chuàng)建數(shù)據(jù)庫對(duì)象(表空間、回滾段、表、索引等)時(shí),根據(jù)對(duì)象的情況設(shè)置合適的storage參數(shù)非常重要。創(chuàng)建對(duì)象設(shè)計(jì)時(shí),對(duì)對(duì)象的容量和預(yù)期的增長有一個(gè)估計(jì),這樣才能確定存儲(chǔ)參數(shù)的大小。一般來說,應(yīng)預(yù)先給表和索引等數(shù)據(jù)庫對(duì)象分配足夠的空間,數(shù)據(jù)庫段不要太多地做動(dòng)態(tài)擴(kuò)展,因?yàn)闀?huì)影響數(shù)據(jù)庫性能。一個(gè)段(segment)由一個(gè)區(qū)(extent)構(gòu)成是最理想的,initial 參數(shù)可以稍大一點(diǎn),如果可能,可設(shè)為最大容量的大小,initial必須是db_block_size的整數(shù)倍;next參數(shù)的設(shè)置比較靈活,根據(jù)應(yīng)用進(jìn)行相應(yīng)的設(shè)置,但也必須是db_block_size的整數(shù)倍;為了減少數(shù)據(jù)庫碎片的產(chǎn)生,pctincrease參數(shù)應(yīng)該盡量設(shè)為0;更新操作比較少的段,pctfree要設(shè)置得小一點(diǎn),更新操作很多的段要設(shè)置得大一些;inittrans和freelists的值要相等,大小與并發(fā)事務(wù)數(shù)相關(guān)。
·分而治之的原則。大的數(shù)據(jù)庫表和索引可考慮進(jìn)行分區(qū)存放,不同的分區(qū)可位于不同的磁盤上,更好地均衡I/O。Oracle可以只對(duì)表的某些分區(qū)進(jìn)行查詢,這樣會(huì)提高查詢的速度;可對(duì)分區(qū)進(jìn)行數(shù)據(jù)的刪除、裝載,還可以移動(dòng)分區(qū),對(duì)表的管理和控制具有更大的靈活性;可以有更多的策略選擇,更好地執(zhí)行備份和恢復(fù)操作。注意,對(duì)某些分區(qū)進(jìn)行操作后,在Oracle8i下必須重建全局索引。
◆大小和增長趨勢(shì)類似的表最好放在相同的表空間,可以有效控制硬盤碎片的產(chǎn)生,提高空閑塊的可重用性。
◆相同備份和恢復(fù)策略的表最好放在同一個(gè)表空間,這樣有助于備份和恢復(fù)工作的完成。
◆對(duì)響應(yīng)時(shí)間要求苛刻的應(yīng)用所訪問的對(duì)象放在速度快的磁盤上。
數(shù)據(jù)庫應(yīng)用系統(tǒng)的設(shè)計(jì)與開發(fā)
1、應(yīng)用設(shè)計(jì)
不論使用何種工具或語言來開發(fā)應(yīng)用程序,都需要進(jìn)行應(yīng)用的全面設(shè)計(jì)。應(yīng)用設(shè)計(jì)包括:
首先,分析應(yīng)用要完成的功能,確定應(yīng)用類型,是OLTP(聯(lián)機(jī)事務(wù)處理)系統(tǒng)、DSS(決策支持)系統(tǒng)還是批處理系統(tǒng);
其次,了解應(yīng)用在何時(shí)由誰使用、應(yīng)用訪問的數(shù)據(jù)、應(yīng)用程序用到的組件、應(yīng)用被要求的響應(yīng)時(shí)間等,在設(shè)計(jì)前,必須對(duì)這些問題盡量進(jìn)行解答,這對(duì)應(yīng)用設(shè)計(jì)特別是大規(guī)模的應(yīng)用設(shè)計(jì)非常重要;
第三,根據(jù)上面的資料,確定應(yīng)用的體系結(jié)構(gòu),是采用client/server兩層架構(gòu)的方式,還是采用browser/server多層架構(gòu)的方式實(shí)現(xiàn)一個(gè)開放的分布式應(yīng)用系統(tǒng),如何對(duì)應(yīng)用服務(wù)器進(jìn)行選擇與配置;
第四,將應(yīng)用按功能劃分為一個(gè)或多個(gè)應(yīng)用程序,明確應(yīng)用程序的具體功能、類型、組成,使用時(shí)間及高峰時(shí)間、事務(wù)的流量、用戶組成、訪問的數(shù)據(jù)庫對(duì)象等,確定應(yīng)用程序間的關(guān)聯(lián)和互操作特性,對(duì)各個(gè)應(yīng)用程序的執(zhí)行時(shí)間合理地進(jìn)行安排;
第五,對(duì)應(yīng)用程序進(jìn)行模塊化設(shè)計(jì),選擇實(shí)現(xiàn)應(yīng)用的數(shù)據(jù)庫組件和開發(fā)語言及工具。
2、應(yīng)用開發(fā)
在應(yīng)用開發(fā)階段,根據(jù)應(yīng)用的不同,實(shí)現(xiàn)的方法和步驟會(huì)有很大的差異。這里只討論以下在應(yīng)用開發(fā)中需要重點(diǎn)注意的幾個(gè)問題。
1) 在開發(fā)會(huì)話關(guān)鍵型應(yīng)用程序時(shí),盡可能使用Pro*C/C++或OCI。在編寫后備實(shí)例和數(shù)據(jù)庫失敗恢復(fù)等需要進(jìn)行數(shù)據(jù)庫重新連接的代碼時(shí),用Pro*C/C++ 或OCI比用PL/SQL要容易實(shí)現(xiàn),在Oracle8/8i中,OCI可以實(shí)現(xiàn)透明應(yīng)用程序失敗恢復(fù)(TAF)。編寫數(shù)據(jù)庫操作繁重的應(yīng)用程序,使用OCI,OCI程序?qū)?shù)據(jù)庫的訪問是通過調(diào)用OCI庫函數(shù)實(shí)現(xiàn)的,能夠直接到達(dá)系統(tǒng)內(nèi)核,比Pro*C/C++速度更快。
2) 在開發(fā)會(huì)話關(guān)鍵型應(yīng)用程序時(shí),盡量實(shí)現(xiàn)失敗檢查和恢復(fù)能力,如指定后備數(shù)據(jù)庫或?qū)嵗?、終止出錯(cuò)客戶進(jìn)程等。
3) 編寫代碼時(shí),要考慮應(yīng)用程序的可維護(hù)性,盡量將應(yīng)用程序獨(dú)立于數(shù)據(jù)庫的變化??墒褂靡晥D、相對(duì)變量類型定義(%TYPE)、記錄型變量定義(%ROWTYPE),采用表驅(qū)動(dòng)的應(yīng)用程序設(shè)計(jì)模式。
4) 進(jìn)行充分的單元測(cè)試和模塊測(cè)試,為應(yīng)用集成打下堅(jiān)實(shí)的基礎(chǔ)。
5) 對(duì)關(guān)鍵表操作的應(yīng)用程序?qū)崿F(xiàn)要特別當(dāng)心,必要的話,在應(yīng)用中對(duì)關(guān)鍵表先做備份,應(yīng)用成功執(zhí)行后再刪除備份表。
6) 編碼結(jié)束后,應(yīng)對(duì)代碼進(jìn)行優(yōu)化。前面提到過,代碼優(yōu)化在數(shù)據(jù)庫應(yīng)用中非常重要,很高比例的性能問題與編碼拙劣的應(yīng)用程序有關(guān)。
7) 定期對(duì)應(yīng)用操作的數(shù)據(jù)庫對(duì)象增長的情況進(jìn)行監(jiān)控,避免因空間不足引起的應(yīng)用程序的失敗。
8) 對(duì)應(yīng)用的數(shù)據(jù)定時(shí)進(jìn)行整理。有些應(yīng)用中,存放在數(shù)據(jù)庫表中的數(shù)據(jù)只要求保存一段時(shí)間,就需要定時(shí)對(duì)數(shù)據(jù)進(jìn)行刪除。如果手工進(jìn)行刪除操作,工作量很大,可以用Oracle提供的作業(yè)來完成, unix系統(tǒng)下可用cron進(jìn)程來實(shí)現(xiàn)。筆者在工作中經(jīng)常使用cron來做數(shù)據(jù)的定時(shí)刪除,根據(jù)應(yīng)用要求,編制Pro*C/C++程序,編寫Shell腳本調(diào)用應(yīng)用程序,將Shell腳本提交給cron進(jìn)程。
注意:在Shell腳本中必須設(shè)置相應(yīng)的Oracle環(huán)境變量,如ORACLE_BASE、ORACLE_HOME、NLS_LANG、LD_LIBRARY_PATH、PATH等,用戶環(huán)境文件中的定義是無效的。
9)對(duì)于大量刪除操作的應(yīng)用程序,如果表是分區(qū)存放的,可對(duì)數(shù)據(jù)分區(qū)執(zhí)行截?cái)啵╰runcate)操作,截?cái)嗖僮鲌?zhí)行速度快并且不會(huì)產(chǎn)生碎片,但截?cái)嗪罂赡苄枰M(jìn)行重建索引的工作。對(duì)大量的數(shù)據(jù)做刪除(delete)操作,會(huì)引起數(shù)據(jù)庫回滾段的急劇增長,建議根據(jù)刪除數(shù)據(jù)量為這類應(yīng)用創(chuàng)建特殊的專用回滾段,為專用回滾段指定合適的storage參數(shù)。平常,專用回滾段可以是離線的(offline),在事物開始前,使專用回滾段在線(online),指定事物使用專用回滾段,事物結(jié)束后再使專用回滾段離線.
【編輯推薦】