觀點sql
1.經過ORM工具,同樣能夠作到由於創建屢次鏈接,執行SQL而使用存儲過程達到減小鏈接獲取的過程。0.5~1s數據庫
2.2005年之前,以數據爲中心的方案,其實很差的就是可移值性,以及集羣環境下的SP執行。適用場景是複雜的報表需求,全表計算,避免把表數據所有加載到應用服務器中計算緩存
3.領域驅運開發DDD的思路就是讓業務邏輯層變得強壯,反而典型就是存儲過程這樣的事務性腳本開發模式。在存儲過程當中包含了太多的業務邏輯。UI層只須要返回調用的結果。沒有中間層。安全
這篇隨筆因爲出差拖了好久,一時也沒整理好該寫些什麼。在google搜了下「存儲過程 優劣」關鍵字,資料並很少,出現了一篇關於來至51cto的關於存儲過程的優缺點的文章,具體這裏也不指出了。看見文章中對存儲過程的幾個辯解,我的不敢苟同,我的已經很仔細的看了文章的時間是2011年,若是在更前寫年成的話,我的以爲徹底可以理解。因此有了這篇,存儲過程的一些傳言。服務器
1:存儲過程只在創造時進行編譯,之後每次執行存儲過程都不需再從新編譯,而通常SQL 語句每執行一次就編譯一次,因此使用存儲過程可提升數據庫執行速度。架構
在sql server 2000版本,這個觀點沒錯,倒是如此。可是在sql server2005文檔中很清晰的寫到 sql server2005的執行任何sql,關係引擎會首先查看緩存,判斷是有有其執行計劃。若是有,則將會重用該執行計劃,以減小從新編譯sql語句生成執行計劃的影響。包括Oracle也是這麼作的,因此在咱們常見的數據庫中不存在這所謂的問題。框架
2:當對數據庫進行復雜操做時(如對多個表進行Update,Insert,Query,Delete 時),可將此複雜操做用存儲過程封裝起來與數據庫提供的事務處理結合一塊兒使用。這些操做,若是用程序來完成,就變成了一條條的SQL語句,可能要屢次鏈接數據庫。而換成存儲,只須要鏈接一次數據庫就能夠了。asp.net
這個問題在前面的架構設計-數據訪問層簡述中說過,DBA老是告訴咱們減小數據庫鏈接次數,這是徹底無爭議的,我表述很贊同。可是必定是存儲過程的優點?或者說除了存儲過程就沒其餘方式?在架構設計-數據訪問層簡述中介紹了來自Martin Fowler《P of EAA》的UOW(工做單元)模式,定義爲工做單元記錄在業務事務過程當中對數據庫有影響的全部變化。操做結束後,做爲一種結果,工做單元瞭解全部須要對數據庫作的改變。其主旨是在內存中創建一個和數據倉庫,維護變化的對象,業務對象變化跟蹤,在業務操做完成一次性提交到數據存儲介質,提供業務事務。這模式已經在咱們常見的ORM(EntityFramework,Nhibernate等)中很好的支持了,或許這麼說這也是ORM框架的一個重要特徵。在好比微軟的DataSet也支持,批量更新。工具
3:存儲過程能夠重複使用,可減小數據庫開發人員的工做量。google
在項目中咱們糜爛的重複代碼僅僅在於數據層?更多或許在於業務邏輯的處理,複雜的條件判斷,數據操做的組合。存儲過程是由開發人員開發,仍是數據庫開發人員?每一個公司的數據庫開發人員就僅僅那幾個吧,我見過的公司。存儲過程是否包含業務規則?若是有的話,業務的不停變化,會不會不停的修改關係模型,修改存儲過程,sql的編寫和調試雖然如今工具備必定的支持,可是我以爲沒有開發語言這麼智能方便吧,至少我還沒看見。若是沒有至少簡單的查詢語句,那和普通的sql有什麼差異?減小開發量爲何不選擇ORM之類的動態sql,採用徹底的對象模型開發,只在少部分ORM失效的業務返璞歸真。
4:若是把全部的數據邏輯都放在存儲過程當中,那麼asp.net只須要負責界面的顯示功能,出錯的可能性最大就是在存儲過程。通常狀況下就是這樣。升級、維護方便。
這句話更離譜。邏輯放在存儲過程,便於維護,我也進入過這樣的公司參與過這樣的項目,因爲剛開始新員工,不能全盤否認,我看見的是惱人的存儲過程,惱人是sql,沒看過那個開發人員喜歡sql,特別在每次項目需求變動的時候。後來慢慢接受ddd模式,把業務從sql中掙脫出來。asp.net只須要負責界面的顯示功能,邏輯層次未免太簡單了,我猜想這應是事務性腳本開發模式,其優劣點在架構設計-業務邏輯層簡述中說過,只能實用於簡單小型的項目。在加上可移植性差,若是你的客戶須要數據庫的升級,sql server到Oracle會怎麼樣。
5:安全性高,可設定只有某此用戶才具備對指定存儲過程的使用權。
安全對於項目來講不只僅在於數據庫,而應是分佈於咱們系統各處。安全關注點應該從表現層到數據庫各層之間都應該有處理。通常比較靈活有效基於角色(域)安全和數據庫安全,物理服務器安全共同使用,這和不適用存儲過程,使用sql並沒什麼衝突。雖然你可能說存儲過程能夠做爲數據庫內部資源實施安全策越。
6:還有些:存儲過程能夠防止sql注入
這個是固然的,毫無爭議。由於用的是參數化方式,你不能隨意拼接字符串,參數化方式可以幫助咱們防止大多數的sql注入。在ado.net中爲咱們提供了很好的參數化支持,使用sql咱們一樣能夠作到,再加上一切開源的安全組件的過濾。
最後存儲過程並非萬惡的,他有他的應用場景,對於複雜邏輯如報表的場景,我會堅決果斷的放棄ORM,選擇它,由於orm不能知足這種複雜查詢,可是準確的說我選擇的是大量的T-SQL或者是P-SQL,存儲過程就是一堆sql子程序的固定格式。我以爲能夠徹底採用ibatis.net方式的xml配置,更爽些。選擇存儲過程是因爲複雜查詢業務,我相信你們也不會爲了一些複雜的統計把全表數據加載到內存吧。存儲過程開發技術流行與2005前數據爲中心的開發模式,在如今的模式,工具,技術下顯得有些蒼老,但並非一無可取。你也能夠徹底採用基於存儲過程的開發模式開發出很好的系統。