存儲過程和觸發器的取捨問題(優缺點分析)

          由於要給同學分享一些關於數據庫中存儲過程和觸發器的知識,我想了想,這是很細節的技術,一般只要用了都會很快掌握其使用方法。經過這麼多年,我一般在設計數據庫的時候也都會或多或少的使用存儲過程和觸發器,原因很簡單:良好的性能,業務也好實現。可是在做上次的項目的時候,由於業務很複雜,存儲過程和觸發器的數量均都達到上百之多,這是一件很恐怖的事情,尤其是在出了錯調試維護的時候,就會想沒有這些東西多好。下面我從經驗角度梳理一下對存儲過程和觸發器的看法。

       1、觸發器是特殊的存儲過程。

         這句話在教科書中會經常出現,這就說明二者是有很大的聯繫的,我的一般理解就是觸發器是一個隱藏的存儲過程,因爲它不需要參數,不需要顯示調用,往往在你不知情的情況下已經做了很多操作。從這個角度來說,由於是隱藏的,無形中增加了系統的複雜性,非DBA人員理解起來數據庫就會有困難,因爲它不執行根本感覺不到它的存在。再有,涉及到複雜的邏輯的時候,觸發器的嵌套是避免不了的,如果再涉及幾個存儲過程,再加上事務等等,很容易出現死鎖現象,再調試的時候也會經常性的從一個觸發器轉到另外一個,級聯關係的不斷追溯,很容易使人頭大。其實,從性能上,觸發器並沒有提升多少性能,只是從代碼上來說,可能在coding的時候很容易實現業務,所以我的觀點是:摒棄觸發器!觸發器的功能基本都可以用存儲過程來實現。

       2、存儲過程優點很多,可以經常使用

  • 可以封裝數據邏輯和業務規則,以便用戶可以僅通過開發人員和數據庫管理員打算使用的方式訪問數據和對象。
  • 驗證所有用戶輸入的參數化存儲過程可用於阻止 SQL 注入攻擊。 如果使用動態 SQL,請確保將命令參數化,並絕對不能將參數值直接包括在查詢字符串中。
  • 可禁止即席查詢和數據修改。 這樣將阻止用戶惡意或無意中損壞數據或執行查詢,以避免降低服務器或網絡的性能。
  • 可以在過程代碼中處理錯誤,而無需將錯誤直接傳遞給客戶端應用程序。 這樣可防止返回錯誤消息,以避免其可能有助於探測攻擊。 在服務器上記錄錯誤並對其進行處理。
  • 存儲過程只能編寫一次,可由很多應用程序訪問。
  • 客戶端應用程序不需要知道有關基礎數據結構的任何信息。 只要更改不影響參數列表或返回的數據類型,就可以更改存儲過程代碼,而無需在客戶端應用程序中進行更改。
  • 存儲過程可通過將多個操作組合到一個過程調用中來減少網絡通訊。
  • 安全性好—可以訪問執行存儲過程而不必擁有直接操作基礎表的權限
  • 減少網絡通信流—存儲過程可以包含多條SQL語句,但只要用一條語句來執行該存儲過程,從而減少了客戶端應用程序對服務器的調用次數和長度
  • 快速執行—存儲過程在第一次執行時進行語法檢查和編譯,編譯好的版本存儲在高速緩存中,用於再次調用
  • 保證一致性—如果用戶只通過存儲過程修改數據,則可以消除偶然修改帶來的問題減少操作人員和編程人員的錯誤—由於傳遞信息少,因此執行復雜任務更容易,不易出現SQL錯誤

        3、考慮移植性,存儲過程的致命傷
        如果一個系統過多的使用了存儲過程,那系統的業務邏輯過於依賴數據庫,這樣就會給系統額外的增加一層數據庫中的業務邏輯層,如果開發的時候用的sql server,後來發現數據量過大,需要提高性能移植到oracle或者mysql,這樣就會很麻煩,相當於把存儲過程重寫一遍,這是不能忍受的。我們平時在做項目的時候,往往一個功能在客戶端實現起來很費勁,在服務端很容易就可以實現,這樣好多人就會選擇在服務端做,卻爲以後留下隱患。在分析項目的需求的時候,一定要考慮性能問題,多久有可能會升級, 如果數據量很小,幾十年用sql server都沒問題,那就可以多用存儲過程;但是數據量有可能會逐漸累積成千萬條甚至更多,就不得不考慮系統的可移植性,這時候儘量不要用存儲過程,全部代碼控制。
        4、存儲過程的代碼可複用性差。
        面向對象的思維在存儲過程這毫無用武之地,兩個很相似的功能在也需要兩個存儲過程,因爲他們是互相獨立的,可以互相調用,但是不能繼承等面向對象的操作,這也就增加了代碼量。

        綜上:在一般的小系統(邏輯簡單)中,存儲過程和觸發器可以多用,畢竟ms設計的,可以很大程度上提升性能;在複雜的系統中,建議不用觸發器,少用存儲過程。

發佈了79 篇原創文章 · 獲贊 16 · 訪問量 59萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章