程序员过关斩将--你为什么还在用存储过程?
菜菜哥,我新接手了一個項目,看的我頭疼呀
業務有這么復雜呀?
不是的,這個老項目完全是用存儲過程寫的,每個存儲過程都好幾百行
這樣呀,是夠頭疼的~
有沒有辦法幫我了解業務一下?
碰到這樣的情況,我真幫不了你了,你可以多埋怨幾句做的那個人~~~
存儲過程存儲過程(Stored Procedure)是在大型數據庫系統中,一組為了完成特定功能的SQL 語句集,它存儲在數據庫中,一次編譯后永久有效,用戶通過指定存儲過程的名字并給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象。
優勢
1. 可以減少程序在調用DB時候的信息傳輸量(其實減少的只有Request的時候)
2. 存儲過程是預先優化和預編譯的,節省每次運行編譯的時間,所以一般情況下認為存儲過程的性能是優于sql語句的。
3. 對調用者可以隱藏數據庫的復雜性,將數據組裝的過程封裝。
4. 參數化的存儲過程可以防止SQL注入式攻擊,而且可以將Grant、Deny以及Revoke權限應用于存儲過程。
5. 如果業務開發中,數據人員和業務代碼人員是分離的,業務人員可以不用關心數據,直接調用存儲過程,更加面向分層開發設計理念。
劣勢
1. 存儲過程這種“一次優化,多次使用”的策略節省了每次執行時候編譯的時間,但也是該策略導致了一個致命的缺點:可能會使用錯誤的執行計劃。
2. 存儲過程難以調試,雖然有些DB提供了調試功能,但是一般的賬號根本就沒有那種權限,更何況線上的數據庫不可能會給你調試權限的,再進一步就算能調試效果也比程序的調試效果要差很多。
3. 可移植性差,當碰到切換數據種類的時候,存儲過程基本就會歇菜。
4. 如果業務數據模型有變動,存儲過程必須跟著業務代碼一起更改,如果是大型項目,這種改動是空前的,是要命的。
不推薦存儲過程以上存儲過程的優缺點,你隨便一下網絡就可能查到,表面看來存儲過程的優勢還是不少的,這也說明為什么老一輩程序員有很多喜歡寫存儲過程。但是隨著軟件行業業務日益復雜化,存儲過程現在在復雜業務面前其實有點有心無力。
菜菜在業務中并不推薦使用存儲過程,辯駁請留言。
1. 采用存儲過程操作數據在網絡數據量傳輸上確實比直接使用sql語句要少很多,但這通常并不是操作數據系統性能的瓶頸,在一次操作數據的過程中,假設用時100毫秒,采用存儲過程節省數據傳輸時間0.5毫秒(就算是5毫秒),我覺得這點時間基本可以忽略。
2. 存儲過程是只優化一次的,這有時候恰恰是個缺陷。有的時候隨著數據量的增加或者數據結構的變化,原來存儲過程選擇的執行計劃也許并不是最優的了,所以這個時候需要手動干預或者重新編譯了,而什么時候執行計劃不是最優的了這個平衡點,預先無法知曉,這就導致了有些應用突然會變慢,程序員處于懵逼的狀態。
3. 存儲過程確實可以對調用方隱藏數據庫的細節,但是這種業務代碼人員和數據庫設計人員是兩個團隊的情況又有多少呢,如果真是兩個團隊,那業務就需要兩個團隊來理解和溝通,我想溝通的成本也一定很高,而且分歧更容易產生。
菜菜認為數據庫就應該做它最擅長的事情:存儲相關。我不止一次的看過把業務寫在存儲過程的情況,程序代碼層面真是薄薄的貧血層,就是一個數據的透傳。我不贊同這種寫法,因為我就接手過這樣的程序,令我頭疼的不是業務,而是看著好幾千行的存儲過程熟悉業務,關鍵還沒有調試的權限(線上更不能調試)。
一個業務系統的設計往往需要你從數據庫的層面抽離出來,把主要精力放在業務模型的設計上,在程序層面體現業務邏輯,而不是把業務邏輯都交給數據層面的管理者。前幾天我排查過一個“Bug”:存儲過程是輸入參數是一個主鍵id的列表字符串,長度居然是 nvarchar(max),主要功能是根據id列表查詢數據。我想說的是就算你是max的長度,也有超長的可能性發生,因為業務方傳輸什么參數,參數什么長度是你DB無法控制的,所以這類的業務一定要放在程序中做處理,而不是懷著僥幸心里丟給DB。
如果是抱著存儲過程性能高的心態的話,我到時覺你這是誤入歧途,菜菜認為存儲過程從來都不是提高性能的關鍵,反而系統的架構,緩存的設計,數據一致性更是系統關鍵問題。
存儲過程通常是一種解決方案,但是通常情況下不是唯一的解決方案,在選擇存儲過程作為方案前,請確保他們是正確的選擇。
最后秀一波存儲過程吧
THE END總結
以上是生活随笔為你收集整理的程序员过关斩将--你为什么还在用存储过程?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记录一次生产发布事件——(简单的非空验证
- 下一篇: asp.net core 集成JWT