做項目的時候我們有時候會面臨一個選擇,我們到底是應該多寫預存程序還是少寫預存程序了?這個問題的爭論也是由來已久,在不同的公司以及不同的技術負責人那裡往往會得到不同的答案。在實際項目中我們最後所採取的方式,往往不外乎以下三種方式。
第一種方式是要求所有資料庫操作不使用任何的預存程序,所有操作都採用標準sql語句來完成,即便是一個動作需要完成多步資料庫操作,也不使用任何預存程序,而是在程式碼中採用事務的方式來完成;第二種方式就是就要求所有的資料庫操作都用預存程序封裝起來,哪怕是一個最簡單的insert 操作。在程式碼看不到一行 sql語句,如果採用分工合作的方式,程式員甚至都可以不懂sql文法。第三種方式是一般相對簡單的資料庫操作採用標準sql語句來完成,一些相對比較複雜的商務邏輯用預存程序來完成。
當然系統如果採用了hibernate或nhibernate之類的架構,不需要寫sql語句的時候,我想還是應該屬於第三種方式,因為在開發的時候hibernate架構允許我們在適當的時候,拋開其架構自己寫預存程序和sql語句來完成資料庫操作。其實這三種方式都各有所長,也各有不足。
第一種方式是所有的資料庫操作都採用標準sql語句來完成的方式,在程式的執行效率上是肯定不如後面兩種方式,系統如果是一個大型的ERP,這種方式就是絕對不可取的。因為在開發基本結束後,系統如果需要最佳化或者希望得到最佳化時,那對開發人員來說就是一件非常麻煩的事情了,因為最佳化的重點基本上都是集中資料庫操作上,開發人員所能做的就是一個個sql語句去檢查,是不是還能進一步最佳化,尤其是一些相對比較複雜的查詢語句是我們所檢查的重點。分頁顯示就是一個典型的預存程序提高程式效率的例子。如果使用預存程序來進行分頁操作,就是利用預存程序從系統中提取我們所需要的記錄集,分頁的效率就大大提高了。反過來如果我們不用預存程序進行分頁操作,是利用sql語句的方式把所有記錄集都讀入記憶體中,然後再從記憶體中擷取我們所需要的記錄集合,這樣分頁效率自然就降低了。當然利用sql語句也能得到我們所需要的記錄,而不是所有記錄,但是那樣麻煩多了,不在我們討論範圍之內。
這種方式另外還有一個不足之處,一個系統或一個項目總會或多或少地存在有一些容易變化而又複雜的商務邏輯,如果把這些複雜的商務邏輯封裝到預存程序中,商務邏輯的變化都只涉及預存程序變化,而與程式碼不發生關係,那麼不用預存程序太可惜了。
這種方式雖然有不足,但是一旦採用這種方式的話,我們如果對該項目進行資料庫移植的時候,開發人員就會覺得當時的決策人是多麼的偉大與英明。而且我們知道access和mysql的以前版本是不提供預存程序支援的,所有一些中小項目在這個方面的選擇往往也是不得已而為之。不用預存程序有一個優點,調試代碼的時候沒有預存程序可是要方便很多很多的哦,所以在很多很多的項目中都是採用標準的sql語句而不使用任何的預存程序。這可是大多程式員用標準sql而不用預存程序的直接原因,說白了,就是嫌麻煩。
第二種方式是所有的資料庫操作全部採用預存程序封裝的方式,如果採用這種方式,程式的執行效率相對要高,尤其面對在一些複雜的商務邏輯時候,不僅在效率方面有明顯的提高,而且當商務邏輯發生變化時,我們開發人員做相應的修改的時候,往往都不用修改程式碼,僅僅修改預存程序就能滿足系統變化了。
還有一個好處就是當我們開發好的一個系統後,如果發現一種模式或語言在某些方面難以滿足需求時,我們就可以很快的用兩外一種語言來重新開發,那個時候就非常方便了。比如在02年中科院下屬的一個公司就用ASP開發了一個B/S結構的HIS,幾乎所有的功能都是用預存程序實現的。杭州婦幼保健醫院在使用過程中由於種種原因要求改成C/S結構的,改的時候就發現當初大量的使用預存程序真是好啊!
全部用預存程序的方式有一個缺點就是程式在開發時調式相當麻煩,因為大家都知道程式錯誤大部分是出在代碼與資料庫互動的時候。回想起來也真是感慨,依稀記得當年在煙台的時候,當時是網通的一個項目,月底時他們從使用者那所收的費用在帳上的金額與實際所收金額對不上,結果熬了一個通宵才搞定,最後找出原因來就是在預存程序中犯了個不起眼的錯誤。
第三種方式就是部分使用預存程序。就是在處理一些複雜的商務邏輯的時候用預存程序封裝,一般比較簡單的資料庫操作還是用標準sql語句的方式。這樣能保證程式的執行效率,同時也能保證一定的開發效率。這種方式也是在實際項目應用最多的方式。
具體一個項目採用哪種方式來做,是需要我們根據具體情況來確定的,不能一概而論。如果項目小、對程式的執行效率要求也不高。而且將來項目還可能做資料庫移植的話,那就採用第一重方式是最好的;如果項目運行一定時間可能採用別的語言來重新開發,那就用第二種方式比較好。
如果是一個很多因素都不太確定的項目,個人認為一般採用第三方式比較好,就是一般的資料庫操作都採用sql語句來實現,當然sql語句最好是標準的 sql語句,而那些相對比較煩瑣的商務邏輯就用預存程序來封裝好了。其實就是只在項目的某些特定的功能模組中採用預存程序的方式而已。這樣做出來的項目既能靈活升級與移植,又能保證程式的執行效率。
扯遠一點,如果是一個比較大型的ERP之類的項目,個人建議hibernate是個不錯的選擇,.net是nhibernate。資料庫操作就省心了。沒有用過的朋友可能剛開始有點排斥,這很正常,但是用熟練就能感覺它好用。跟微軟當年一樣,一開排斥. com組件技術,因為他們沒有掌握,但是後來掌握以後,就極力推廣之。