基本servlet設計 我們使用標准JDBC調用來構建我們的servlet,通過DB2 Information Integrator和本地客戶端接口(無DB2 Information Integrator)訪問數據。只要有可能,我們就使用DataSource連接(連接池),這樣能夠更有效的利用系統資源。更進一步,我們通過執行JNDI在每個servlet的init方法中查找DataSource,設法維護編碼效率。
當我們通過DB2 Information Integrator訪問遠程數據的時候,我們的servlet發出針對別名或者跨多個別名的UNION ALL視圖的查詢。當直接訪問遠程數據的時候,我們的servlet發出針對每個數據源的查詢。然後,我們必須確定如何整合返回的結果。
我們可以在我們的servlet中手工完成這些整合工作,編寫必要的代碼根據需要組合、分類和分組這些數據。 然而,這將會有很大的工作量。 取而代之,我們選擇利用一個本地DBMS表來幫助我們的工作,我們這麼做的原因是這樣的軟件對於大多數WebSphere開發者也是有用的。 在從每個數據源檢索到適當的數據以後,我們的servlet把結果插入一個本地DB2數據庫的輔助表中,並且查詢這些表以獲得最後的結果。 當然,我們試著去過濾盡可能多的位於遠程數據源的數據,來最小化網絡通信量並進一步提高我們的本地servlet的效率。
假如這聽上去很含糊,那麼讓我們研究一個簡單的例子。 想象我們需要構建一個servlet,不使用DB2 Information Integrator,報告一套零件的最低供給價格。 在與我們三個數據源中的每一個連接之後,我們的servlet將查詢每一個數據源上PARTSUPP數據,來找到這些零件的最低供給價格。 (SQL語句可能看起來像Select MIN ( ps_supplycost) from PARTSUPP where ps_partkey IN ( list of ps_partkeys) group by ps_partkey。) servlet然後將把價格信息儲存到一個本地臨時表中,這個表兩個列:ps_partkey和ps_supplycost。 最後,這個servlet可能發出一個針對本地表的查詢,計算最小的ps_supplycost值,使用ps_partkey分組。
緊接著,是實現我們直接使用直接數據訪問的servlet的基本程序邏輯。 當然,程序比僅僅編寫一個簡單的查詢要更復雜,我們要編寫當我們使用DB2 Information Integrator進行數據訪問的時候,我們要做什麼。但是到底有多復雜呢?請接著向下讀。
現在,你可能對我們從我們的工作中了解到的東西感到好奇。 我們將在本文中總結我們的結論,然後在後續的文章中向你說明我們怎樣得到這些結論。 但是歸根到底還是那句話:我們發現,當我們使用DB2 Information Integrator的時候,構建servlet更為輕易。
為什麼?因為使用DB2 Information Integrator (II):
· 我們需要實現的數據訪問邏輯要少些。大約少40%的代碼量。
· 我們不必為如何把我們的查詢正確地分解為用於每一種目標數據源而擔心。這節省了我們無數的時間和沉悶的調試工作。它還讓我們更加輕易獲得我們想要的結果!
· 我們不必協調我們的數據訪問程序邏輯。 比如說,我們不必研究我們的數據是如何被分配以便作出適當的聯接過程程序邏輯。 我們讓DB2 II的優化程序為我們做這些工作。 通常它能做得很好,有時甚至比我們手寫的程序更要優秀。
設計數據訪問程序邏輯 因為我們的servlet是數據集中的,它們的代碼大多數包括數據訪問程序邏輯。 利用DB2 Information Integrator,我們的servlet連接到單一的基本數據服務器,發出單一查詢,然後分布它們取得的資源集。 假如不使用DB2 Information Integrator,我們的servlet分別連接到每個數據源,每個數據源至少要發出一條查詢,把從每個數據源中檢索得到的數據放入至少一個本地臨時輔助表中,付出用於輔助表的(最後)一個查詢,清除輔助表的內容,發布它們取得的所有的本地的和遠程的資源。
當然,這需要更多的編碼要實現。 此外,假如沒有DB2 Information Integrator,它會花費我們成倍的時間來實現我們的servlet,因其工作的復雜性。 並且這個復雜性的大部分是如何把每個查詢都正確的分解為針對每種數據源。
取得正確的查詢 當直接使用不同的數據源工作的時候,我們知道我們必須發出針對每個數據源的查詢,取得結果,並執行一些最終操作過程來返回我們尋找的信息。 要想不花費我們很長時間去實現為每個遠程數據源都發出查詢是很不輕易的。
為了保證我們的本地實現的性能,我們得盡可能多地過濾每個後端數據源上的數據。 例如,查詢2包含一個WHERE子句,指定一個特定的零件鍵值。 這種檢索謂詞相當有選擇性,並且應被推到數據源以避免不需要的數據傳送。
不幸的是,並不是所有查詢都可以簡單的協調連接到每個數據源。 帶有某些聚合函數和FETCH FIRST n ROWS子句的查詢需要被非凡小心的處理。 有時,當你試圖合並最後的結果的時候,把它們推到每個後端數據源可能導致不正確的信息。
假如這聽起來有點含糊,那麼我們將在下一篇文章中帶你進入一個具體的例子。 你會看到,在不破壞我們的查詢的語義的情況下,我們是不能在查詢5中傳送AVG函數的。 取而代之,我們必須使用SUM和COUNT(*)函數 ,用於我們的後端數據源查詢。 然後,在我們合並結果到一個輔助表之後,我們必須把數據分為兩欄,並且針對每個客戶計算平均值。
這樣,確定如何正確地分解復雜的查詢,以便性能不受損害以及我們工作的完善性不會被破壞,就變成了一個耗時的並且易於出錯的過程。 然而,值得一提的是,DB2 Information Integrator可以為你自動的治理這個困難的任務,作為它全局查詢最優化工作的一部分。
確定數據存取策略 我們的一些查詢包括不同地址的兩個以上表的連接。 尤其是,查詢4和查詢5有這個特征。 假如你熟悉關系數據庫治理系統,那麼你應該知道所有支持用於高效處理的多連接方法的主要商業產品。 表的大小和索引的有效性可能較大程度地影響這種數據庫治理系統優化程序可能為一個給定的查詢選擇的用來保證其性能的連接方法。
當你必須在沒有聯合數據庫治理系統的情況下,連接跨不同數據源的數據的時候,你必須擔負起如何有效地處理連接的責任。 最簡單方法--檢索來自每個數據源的所有的行並且在本地治理連接--可能導致很差的性能。 但是得到最好的方法並不是那麼輕易,尤其是假如你沒有訪問一個全局目錄的權力的時候,你就得不到關於遠程表和索引有效性得統計數據。
我們必須面對我們的一些查詢中的問題,我們很快發現對於數據分布不同的假設可能導致我們采用不同的方法來實現我們的servlet程序邏輯。 並且,假如我們的數據分布情況將來將改變,假如新的索引被創建,或者假如現有的索引被刪除,那麼我們的servlet的性能可能會下降,可能會迫使我們又要修改我們的代碼。 這是另一個如何使用聯合數據庫治理系統的例子,能讓我們使用很少的工作量就可以完成我們的開發工作。
總結 構建需要整合來自於多個數據源的數據的網絡組件不是很平常的任務。 幸運的是,聯合數據庫治理系統技術的新發展幫助我們減輕了很多做此類相關事情的負擔。
我們構建需要整合來自多個數據源的數據的servlet。 一類使用DB2 Information Integrator,而另一類直接訪問每個數據源。 我們的經驗顯示,當我們使用DB2 Information Integrator提供訪問不同數據源的透明性的時候,設計、開發和維護工作明顯減少。 在我們的例子中,我們減少了代碼量達40%。 此外,我們不必進行試圖確定如何有效地分配我們的查詢到每個數據源,以最小化不必要的數據傳送這個令人煩惱的、耗時的任務,同時仍然能夠保持我們工作的完善性。 我們通過依靠DB2 Information Integrator固有的全局優化能力完成這個任務,它答應我們在保持性能的同時獲得正確結果。(全文完)