基于中間件的查詢優(yōu)化模型
傳統(tǒng)的客戶/服務(wù)器模式是一種雙層的結(jié)構(gòu),通常是一臺個人計算機(jī)做客戶機(jī)使用(運(yùn)行客戶端程序),另外一臺服務(wù)器用于存放后臺的
數(shù)據(jù)庫系統(tǒng),應(yīng)用程序可客戶端直接相連,中間沒有其他的邏輯。在MIS系統(tǒng)的軟件開發(fā)過程中,查詢數(shù)據(jù)是必不可少的一個重要部分,而如何幫助用戶在數(shù)據(jù)庫中進(jìn)行快速而有效的查詢數(shù)據(jù)是軟件開發(fā)人員十分關(guān)心的事情。我從我做過的2個MIS系統(tǒng)中關(guān)于數(shù)據(jù)查詢方面,大致總結(jié)出以下幾種方法:
1. 固定結(jié)構(gòu)方式:即程序員根據(jù)客戶的業(yè)務(wù)要求定制客戶端查詢程序,這種定制的程序沒有通用性。或者業(yè)務(wù)邏輯也存在于后臺數(shù)據(jù)庫中,以觸發(fā)器(trigger)的方式實現(xiàn)。這種方式有一個很大的缺點(diǎn),就是一旦客戶的業(yè)務(wù)邏輯有所改變的話,將引起應(yīng)用程序的修改以及后臺觸發(fā)器的修改,將所有程序模塊都重新修改、編譯、連接的工作量是相當(dāng)大的。另外由于這種結(jié)構(gòu)將用戶界面和業(yè)務(wù)邏輯以及數(shù)據(jù)源綁定在一起,會消耗客戶機(jī)的大量資源,對客戶機(jī)來說是一個很大的負(fù)擔(dān)。
2. 靈活結(jié)構(gòu)方式:既除了使用固定查詢命令以外,再做一些讓系統(tǒng)管理人員可以修改查詢命令的界面。也就是讓系統(tǒng)管理人員可以編寫
SQL語句的方式,這種方式雖然可以提高查詢質(zhì)量,但對與非專業(yè)的操作人員來講,是很困難的。
3. 基于中間件的數(shù)據(jù)查詢優(yōu)化模型:本文就以中間件和分布式系統(tǒng)為理論基礎(chǔ),以曾經(jīng)開發(fā)過的成都市康泰電器MIS系統(tǒng)為例介紹這種數(shù)據(jù)查詢模型,相信它給用戶提供了更方便和更快速的服務(wù)。
1. 什么是中間件:
2. 開發(fā)人員在做查詢模塊的時候應(yīng)該注意的問題:
一般來說,客戶只關(guān)心他們所需要的數(shù)據(jù)和怎樣查詢出這些數(shù)據(jù),而對與這條查詢語句是和生成的,就不會關(guān)心了。舉一個例子,一個庫房管理系統(tǒng),包括入庫情況,出庫情況和結(jié)存情況等等。客戶只關(guān)心如何得到一個產(chǎn)品的出庫數(shù)量,入庫數(shù)量和當(dāng)前的結(jié)存數(shù)量。而對于這個庫房管理系統(tǒng)是如何生成,和查詢語句的SQL代碼和數(shù)據(jù)表,一律不感興趣。以康泰電器MIS系統(tǒng)為例,它采用的是client/server結(jié)構(gòu),根據(jù)我對MIS系統(tǒng)的了解,只要應(yīng)用系統(tǒng)的客戶端數(shù)目在200個用戶以內(nèi)而且是在同一個局域網(wǎng)內(nèi),那么client/server結(jié)構(gòu)在執(zhí)行MIS系統(tǒng)就足夠了。但是,眾所周知client/server結(jié)構(gòu)存在很多問題。既前面固定結(jié)構(gòu)方式中所談到的一些問題,導(dǎo)致它影響了數(shù)據(jù)庫的執(zhí)行效率。
加上近年來INTERNET/INTRANET應(yīng)用的興起,對于企業(yè)的運(yùn)作方式有了重大的影響,康泰電器的企業(yè)主管要求開發(fā)產(chǎn)品查詢的信息給所有在INTERNET/INTRANET上的潛在用戶,所以MIS系統(tǒng)必須能夠讓客戶使用瀏覽器來查詢所有的產(chǎn)品信息,事實上系統(tǒng)結(jié)構(gòu)已經(jīng)進(jìn)入了分布式的結(jié)構(gòu)了。因為它多了一臺WEB 服務(wù)器。以前的系統(tǒng)要提供INTERNET/INTRANET的存取形式時,舊的MIS系統(tǒng)必然以新的技術(shù)編寫一次。這必然加大了開發(fā)人員的工作,也提高了成本。所以我想,只是由于多了B/S的查詢方式,為什么不利用現(xiàn)在流行的中間件的思想開發(fā)一個新的查詢模型呢?
3.查詢系統(tǒng)的模型:
我通過分析一些查詢的語句,了解到了他們的一些共同性,并且共同性比較
突出,因為他們不是離散出現(xiàn)的。比如所有關(guān)于庫房查詢的語句構(gòu)成了庫房管理查詢系統(tǒng),所有財務(wù)收支的查詢語句構(gòu)成了收支查詢系統(tǒng),我將查詢的語句進(jìn)行分類處理,structN_class={Table1,Table2…..Tablen};Datawarehouse={ struct 1_class, struct 2_class……structN_class}.而我就是要在structN_class上使用微軟的DCOM 技術(shù)創(chuàng)建我們的查詢系統(tǒng)。
它的主要技術(shù)特征是把查詢語句和系統(tǒng)的界面完全分開,不是原來的client/server結(jié)構(gòu)了,我把client分為2個部分,client和SelectCom-Server.。不管用戶是在client端,還是在采用瀏覽器界面。把用戶輸入的查詢條件和類別先提交到SelectCom-Server. SelectCom-Server.根據(jù)用戶輸入的查詢條件和類別自動生成查詢語句。然后把它們提交給數(shù)據(jù)庫,最后數(shù)據(jù)庫運(yùn)行查詢語句,再將查詢 的數(shù)據(jù)交給SelectCom-Server. SelectCom-Server.在把數(shù)據(jù)返回給client端,這樣就完成了查詢工作。
我認(rèn)為它的好處有以下幾點(diǎn):
由于SelectCom-Server.和client是分離的,那么一個用戶使用過的查詢條件可以被其它用戶使用共享。這樣使網(wǎng)絡(luò)和數(shù)據(jù)庫的開銷大大降低了。還可以根據(jù)已經(jīng)使用過的查詢條件來縮小查詢的范圍。在由于我已經(jīng)把深一級的權(quán)限加在了SelectCom-Server.上,它就可以拒絕一些核心數(shù)據(jù)的查詢,提高了數(shù)據(jù)的安全性
也減輕了代碼的從用性,因為這種分布式的系統(tǒng),考慮安全性按照常規(guī)不僅要完善client/server結(jié)構(gòu),而且要完善B/S結(jié)構(gòu)。再者,它還有利與系統(tǒng)管理人員的維護(hù),他要排錯就只需要對SelectCom-Server.上的查詢語句進(jìn)行分析。
4實現(xiàn):
限與篇幅的問題,我不會把DCOM實現(xiàn)的代碼寫出來,因為這種分布式系統(tǒng)接口編程牽涉到的東西太多了,只是談一下查詢語句的構(gòu)成原理和它的優(yōu)化,這才是最主要的。
但是這其中牽涉的東西也很多,比如:合理使用索引,避免或簡化排序,消除對大型表行數(shù)據(jù)的順序存取,避免相關(guān)子查詢,用排序來取代非順序存取等等。
先說構(gòu)成的原理,查詢subsentence的生成依據(jù)是各個字段屬于哪個關(guān)系表而產(chǎn)生的,當(dāng)同一個字段屬于2個關(guān)系表共同擁有的時候,那么它就是連接的字段。
例如有3個關(guān)系表:
table1(Rnumber,Name,Guige),table2(Cnumber,Xinghao,Guige),table3(Score,Guige)
那么可以生成一個查詢subsentence的成員N=table1.Guige= table2.Guige.
而對于如何實現(xiàn)一個用戶使用過的查詢條件可以被其它用戶使用共享如下所敘述:關(guān)鍵是建立臨時文件,(我把其優(yōu)化方式也加在其中)。以曾經(jīng)開發(fā)過的成都市康泰電器MIS系統(tǒng)為例,把表的一個子集進(jìn)行排序并創(chuàng)建臨時表,有時能加速查詢。它有助于避免多重排序操作,而且在其他方面還能簡化優(yōu)化器的工作。例如:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>“98000”
ORDER BY cust.name
如果這個查詢要被執(zhí)行多次而不止一次,可以把所有未付款的客戶找出來放在一個臨時文件中,并按客戶的名字進(jìn)行排序:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name
INTO TEMP cust_with_balance
然后以下面的方式在臨時表中查詢:
SELECT * FROM cust_with_balance
WHERE postcode>“98000”
臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁盤I/O,所以查詢工作量可以得到大幅減少。為了加速查詢語句的生成和搜索我們使用的臨時緩存表。進(jìn)行搜索時,首先搜索臨時緩存表,再搜索語句生成表。
但是要注意的是臨時表創(chuàng)建后不會反映主表的修改。在主表中數(shù)據(jù)頻繁修改的情況下,注意不要丟失數(shù)據(jù)。但是我到現(xiàn)在還沒有完全的解決這個問題,有興趣的讀者可以想想。
5.查詢語句的存儲結(jié)構(gòu):
一個查詢語句可以分解成一個或許多的查詢subsentence,一個查詢subsentence還可以分解成多個更小的查詢subsentence。實際上他們是一個樹型結(jié)構(gòu),所以每一個新的查詢語句就是新的父節(jié)點(diǎn)。我們的臨時緩存表就是已這種結(jié)構(gòu)進(jìn)行存儲的。
6.結(jié)束語
此模型在實際的運(yùn)用中運(yùn)行良好,而且對于用戶來說簡單實用,基本滿足了用戶的分布式系統(tǒng)的要求。盡管用戶對查詢的要求不一致,但是利用基于中間件的查詢優(yōu)化模型具有友好的人機(jī)交互界面,查詢條件能夠自動靈活的生成,增加了實用性。對于開發(fā)人員來說減少了工作量,在提高了數(shù)據(jù)的安全性的同時也減輕了代碼的二次開發(fā)等等。