當前位置:
首頁 > 知識 > 程序員過關斬將-你為什麼還在用存儲過程?

程序員過關斬將-你為什麼還在用存儲過程?

存儲過程

存儲過程(Stored Procedure)是在大型資料庫系統中,一組為了完成特定功能的SQL 語句集,它存儲在資料庫中,一次編譯後永久有效,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是資料庫中的一個重要對象。

優勢

可以減少程序在調用DB時候的信息傳輸量(其實減少的只有Request的時候)

存儲過程是預先優化和預編譯的,節省每次運行編譯的時間,所以一般情況下認為存儲過程的性能是優於sql語句的。

對調用者可以隱藏資料庫的複雜性,將數據組裝的過程封裝。

參數化的存儲過程可以防止SQL注入式攻擊,而且可以將Grant、Deny以及Revoke許可權應用於存儲過程。

如果業務開發中,數據人員和業務代碼人員是分離的,業務人員可以不用關心數據,直接調用存儲過程,更加面向分層開發設計理念。

劣勢

存儲過程這種「一次優化,多次使用」的策略節省了每次執行時候編譯的時間,但也是該策略導致了一個致命的缺點:可能會使用錯誤的執行計劃。

存儲過程難以調試,雖然有些DB提供了調試功能,但是一般的賬號根本就沒有那種許可權,更何況線上的資料庫不可能會給你調試許可權的,再進一步就算能調試效果也比程序的調試效果要差很多。

可移植性差,當碰到切換數據種類的時候,存儲過程基本就會歇菜。

如果業務數據模型有變動,存儲過程必須跟著業務代碼一起更改,如果是大型項目,這種改動是空前的,是要命的。

不推薦存儲過程

以上存儲過程的優缺點,你隨便一下網路就可能查到,表面看來存儲過程的優勢還是不少的,這也說明為什麼老一輩程序員有很多喜歡寫存儲過程。但是隨著軟體行業業務日益複雜化,存儲過程現在在複雜業務面前其實有點有心無力。

菜菜在業務中並不推薦使用存儲過程,辯駁請留言

採用存儲過程操作數據在網路數據量傳輸上確實比直接使用sql語句要少很多,但這通常並不是操作數據系統性能的瓶頸,在一次操作數據的過程中,假設用時100毫秒,採用存儲過程節省數據傳輸時間0.5毫秒(就算是5毫秒),我覺得這點時間基本可以忽略。

存儲過程是只優化一次的,這有時候恰恰是個缺陷。有的時候隨著數據量的增加或者數據結構的變化,原來存儲過程選擇的執行計劃也許並不是最優的了,所以這個時候需要手動干預或者重新編譯了,而什麼時候執行計劃不是最優的了這個平衡點,預先無法知曉,這就導致了有些應用突然會變慢,程序員處於懵逼的狀態。

存儲過程確實可以對調用方隱藏資料庫的細節,但是這種業務代碼人員和資料庫設計人員是兩個團隊的情況又有多少呢,如果真是兩個團隊,那業務就需要兩個團隊來理解和溝通,我想溝通的成本也一定很高,而且分歧更容易產生。

菜菜認為資料庫就應該做它最擅長的事情:存儲相關。我不止一次的看過把業務寫在存儲過程的情況,程序代碼層面真是薄薄的貧血層,就是一個數據的透傳。我不贊同這種寫法,因為我就接手過這樣的程序,令我頭疼的不是業務,而是看著好幾千行的存儲過程熟悉業務,關鍵還沒有調試的許可權(線上更不能調試)。

一個業務系統的設計往往需要你從資料庫的層面抽離出來,把主要精力放在業務模型的設計上,在程序層面體現業務邏輯,而不是把業務邏輯都交給數據層面的管理者。前幾天我排查過一個「Bug」:存儲過程是輸入參數是一個主鍵id的列表字元串,長度居然是 nvarchar(max),主要功能是根據id列表查詢數據。我想說的是就算你是max的長度,也有超長的可能性發生,因為業務方傳輸什麼參數,參數什麼長度是你DB無法控制的,所以這類的業務一定要放在程序中做處理,而不是懷著僥倖心裡丟給DB。

如果是抱著存儲過程性能高的心態的話,我到時覺你這是誤入歧途,菜菜認為存儲過程從來都不是提高性能的關鍵,反而系統的架構,緩存的設計,數據一致性更是系統關鍵問題。

存儲過程通常是一種解決方案,但是通常情況下不是唯一的解決方案,在選擇存儲過程作為方案前,請確保他們是正確的選擇。

最後秀一波存儲過程吧

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 千鋒JAVA開發學院 的精彩文章:

技術分享:Golang並發編程
技術分享:Flink 基本的 API

TAG:千鋒JAVA開發學院 |