由於要給同學分享一些關於數據庫中存儲過程和觸發器的知識,我想了想,這是很細節的技術,一般只要用了都會很快掌握其使用方法。經過這麼多年,我一般在設計數據庫的時候也都會或多或少的使用存儲過程和觸發器,原因很簡單:良好的性能,業務也好實現。可是在做上次的項目的時候,由於業務很複雜,存儲過程和觸發器的數量均都達到上百之多,這是一件很恐怖的事情,尤其是在出了錯調試維護的時候,就會想沒有這些東西多好。下面我從經驗角度梳理一下對存儲過程和觸發器的看法。
1、觸發器是特殊的存儲過程。
這句話在教科書中會經常出現,這就說明二者是有很大的聯繫的,我的一般理解就是觸發器是一個隱藏的存儲過程,因爲它不需要參數,不需要顯示調用,往往在你不知情的情況下已經做了很多操作。從這個角度來說,由於是隱藏的,無形中增加了系統的複雜性,非DBA人員理解起來數據庫就會有困難,因爲它不執行根本感覺不到它的存在。再有,涉及到複雜的邏輯的時候,觸發器的嵌套是避免不了的,如果再涉及幾個存儲過程,再加上事務等等,很容易出現死鎖現象,再調試的時候也會經常性的從一個觸發器轉到另外一個,級聯關係的不斷追溯,很容易使人頭大。其實,從性能上,觸發器並沒有提升多少性能,只是從代碼上來說,可能在coding的時候很容易實現業務,所以我的觀點是:摒棄觸發器!觸發器的功能基本都可以用存儲過程來實現。
2、存儲過程優點很多,可以經常使用
- 可以封裝數據邏輯和業務規則,以便用戶可以僅通過開發人員和數據庫管理員打算使用的方式訪問數據和對象。
- 驗證所有用戶輸入的參數化存儲過程可用於阻止 SQL 注入攻擊。 如果使用動態 SQL,請確保將命令參數化,並絕對不能將參數值直接包括在查詢字符串中。
- 可禁止即席查詢和數據修改。 這樣將阻止用戶惡意或無意中損壞數據或執行查詢,以避免降低服務器或網絡的性能。
- 可以在過程代碼中處理錯誤,而無需將錯誤直接傳遞給客戶端應用程序。 這樣可防止返回錯誤消息,以避免其可能有助於探測攻擊。 在服務器上記錄錯誤並對其進行處理。
- 存儲過程只能編寫一次,可由很多應用程序訪問。
- 客戶端應用程序不需要知道有關基礎數據結構的任何信息。 只要更改不影響參數列表或返回的數據類型,就可以更改存儲過程代碼,而無需在客戶端應用程序中進行更改。
- 存儲過程可通過將多個操作組合到一個過程調用中來減少網絡通訊。
- 安全性好—可以訪問執行存儲過程而不必擁有直接操作基礎表的權限
- 減少網絡通信流—存儲過程可以包含多條SQL語句,但只要用一條語句來執行該存儲過程,從而減少了客戶端應用程序對服務器的調用次數和長度
- 快速執行—存儲過程在第一次執行時進行語法檢查和編譯,編譯好的版本存儲在高速緩存中,用於再次調用
- 保證一致性—如果用戶只通過存儲過程修改數據,則可以消除偶然修改帶來的問題減少操作人員和編程人員的錯誤—由於傳遞信息少,因此執行復雜任務更容易,不易出現SQL錯誤