存储过程的优缺点 (转载)
為什么要用存儲(chǔ)過程
?
幾個(gè)去 IBM 面試的兄弟回來(lái)抱怨:去了好幾個(gè)不同的 IBM 項(xiàng)目組,幾乎每個(gè)面試官問到數(shù)據(jù)庫(kù)的時(shí)候都要問用沒用過存儲(chǔ)過程,煩人不?大家去面的程序員,又不是 DBA,以前的項(xiàng)目都沒有用到存儲(chǔ),不照樣運(yùn)行的好好的?
存儲(chǔ)過程真的那么重要嗎,它到底有什么好處呢?
筆者認(rèn)為,存儲(chǔ)過程說(shuō)白了就是一堆 SQL 的合并。中間加了點(diǎn)邏輯控制。
但是存儲(chǔ)過程處理比較復(fù)雜的業(yè)務(wù)時(shí)比較實(shí)用。
比如說(shuō),一個(gè)復(fù)雜的數(shù)據(jù)操作。如果你在前臺(tái)處理的話。可能會(huì)涉及到多次數(shù)據(jù)庫(kù)連接。但如果你用存儲(chǔ)過程的話。就只有一次。從響應(yīng)時(shí)間上來(lái)說(shuō)有優(yōu)勢(shì)。
也就是說(shuō)存儲(chǔ)過程可以給我們帶來(lái)運(yùn)行效率提高的好處。
另外,程序容易出現(xiàn) BUG 不穩(wěn)定,而存儲(chǔ)過程,只要數(shù)據(jù)庫(kù)不出現(xiàn)問題,基本上是不會(huì)出現(xiàn)什么問題的。也就是說(shuō)從安全上講,使用了存儲(chǔ)過程的系統(tǒng)更加穩(wěn)定。
數(shù)據(jù)量小的,或者和錢沒關(guān)系的項(xiàng)目不用存儲(chǔ)過程也可以正常運(yùn)作。MySQL 的存儲(chǔ)過程還有待實(shí)際測(cè)試。如果是正式項(xiàng)目,建議你用 sql server 或 Oracle 的存儲(chǔ)過程。數(shù)據(jù)與數(shù)據(jù)之間打交道的話,過程會(huì)比程序來(lái)的快的多。面試官問有沒有用存儲(chǔ),實(shí)際上就是想知道前來(lái)面試的程序員到底做過數(shù)據(jù)量大的項(xiàng)目沒。如果是培訓(xùn)出來(lái)的,或者小項(xiàng)目小公司出來(lái)的,對(duì)存儲(chǔ)肯定接觸的少了。
所以,要想進(jìn)大公司,沒有豐富存儲(chǔ)過程經(jīng)驗(yàn),是不行的。
那么什么時(shí)候才可以用存儲(chǔ)?對(duì)于數(shù)據(jù)量不是很大以及業(yè)務(wù)處理不是很復(fù)雜的小項(xiàng)目就無(wú)需要了么?
錯(cuò)。存儲(chǔ)過程不僅僅適用于大型項(xiàng)目,對(duì)于中小型項(xiàng)目,使用存儲(chǔ)過程也是非常有必要的。其威力和優(yōu)勢(shì)主要體現(xiàn)在:
? 1.存儲(chǔ)過程只在創(chuàng)造時(shí)進(jìn)行編譯,以后每次執(zhí)行存儲(chǔ)過程都不需再重新編譯,而一般 SQL 語(yǔ)句每執(zhí)行一次就編譯一次,所以使用存儲(chǔ)過程可提高數(shù)據(jù)庫(kù)執(zhí)行速度。
? 2.當(dāng)對(duì)數(shù)據(jù)庫(kù)進(jìn)行復(fù)雜操作時(shí)(如對(duì)多個(gè)表進(jìn)行 Update,Insert,Query,Delete 時(shí)),可將此復(fù)雜操作用存儲(chǔ)過程封裝起來(lái)與數(shù)據(jù)庫(kù)提供的事務(wù)處理結(jié)合一起使用。這些操作,如果用程序來(lái)完成,就變成了一條條的 SQL 語(yǔ)句,可能要多次連接數(shù)據(jù)庫(kù)。而換成存儲(chǔ),只需要連接一次數(shù)據(jù)庫(kù)就可以了。
? 3.存儲(chǔ)過程可以重復(fù)使用,可減少數(shù)據(jù)庫(kù)開發(fā)人員的工作量。
? 4.安全性高,可設(shè)定只有某此用戶才具有對(duì)指定存儲(chǔ)過程的使用權(quán)。
?
存儲(chǔ)過程的使用,好像一直是一個(gè)爭(zhēng)論。????
? 我不傾向于盡可能使用存儲(chǔ)過程,是這么認(rèn)為的:????
? 1.?? 運(yùn)行速度:?? 大多數(shù)高級(jí)的數(shù)據(jù)庫(kù)系統(tǒng)都有statement?? cache的,所以編譯sql的花費(fèi)沒什么影響。但是執(zhí)行存儲(chǔ)過程要比直接執(zhí)行sql花費(fèi)更多(檢查權(quán)限等),所以對(duì)于很簡(jiǎn)單的sql,存儲(chǔ)過程沒有什么優(yōu)勢(shì)。????
? 2.?? 網(wǎng)絡(luò)負(fù)荷:如果在存儲(chǔ)過程中沒有多次數(shù)據(jù)交互,那么實(shí)際上網(wǎng)絡(luò)傳輸量和直接sql是一樣的。????
? 3.?? 團(tuán)隊(duì)開發(fā):很遺憾,比起成熟的IDE,沒有什么很好存儲(chǔ)過程的IDE工具來(lái)支持,也就是說(shuō),這些必須手工完成。????
? 4.?? 安全機(jī)制:對(duì)于傳統(tǒng)的C/S結(jié)構(gòu),連接數(shù)據(jù)庫(kù)的用戶可以不同,所以安全機(jī)制有用;但是在web的三層架構(gòu)中,數(shù)據(jù)庫(kù)用戶不是給用戶用的,所以基本上,只有一個(gè)用戶,擁有所有權(quán)限(最多還有一個(gè)開發(fā)用戶)。這個(gè)時(shí)候,安全機(jī)制有點(diǎn)多余。????
? 5.?? 用戶滿意:實(shí)際上這個(gè)只是要將訪問數(shù)據(jù)庫(kù)的接口統(tǒng)一,是用存儲(chǔ)過程,還是EJB,沒太大關(guān)系,也就是說(shuō),在三層結(jié)構(gòu)中,單獨(dú)設(shè)計(jì)出一個(gè)數(shù)據(jù)訪問層,同樣能實(shí)現(xiàn)這個(gè)目標(biāo)。????
? 6.?? 開發(fā)調(diào)試:一樣由于IDE的問題,存儲(chǔ)過程的開發(fā)調(diào)試要比一般程序困難(老版本DB2還只能用C寫存儲(chǔ)過程,更是一個(gè)災(zāi)難)。????
? 7.?? 移植性:算了,這個(gè)不用提,反正一般的應(yīng)用總是綁定某個(gè)數(shù)據(jù)庫(kù)的,不然就無(wú)法靠?jī)?yōu)化數(shù)據(jù)庫(kù)訪問來(lái)提高性能了。????
? 8.?? 維護(hù)性:的確,存儲(chǔ)過程有些時(shí)候比程序容易維護(hù),這是因?yàn)榭梢詫?shí)時(shí)更新DB端的存儲(chǔ)過程,但是在3層結(jié)構(gòu)下,更新server端的數(shù)據(jù)訪問層一樣能實(shí)現(xiàn)這個(gè)目標(biāo),可惜現(xiàn)在很多平臺(tái)不支持實(shí)時(shí)更新而已。????
???
? 從上面可知道,存儲(chǔ)過程的使用不能有死規(guī)定(全用,或全不用),以前Terminal?? -?? Server,?? Client-DB的方式已經(jīng)過時(shí)了,存儲(chǔ)過程很多優(yōu)勢(shì)已經(jīng)不明顯。????
? 現(xiàn)在,我認(rèn)為的原則是:所有數(shù)據(jù)訪問在應(yīng)用層封裝為數(shù)據(jù)訪問層,在那里,如果SQL簡(jiǎn)單的話,直接用SQL;如果SQL復(fù)雜,或者數(shù)據(jù)交互多且中間數(shù)據(jù)最后不會(huì)用到,使用存儲(chǔ)過程。其他憑經(jīng)驗(yàn)吧。
?
存儲(chǔ)過程是由一些SQL語(yǔ)句和控制語(yǔ)句組成的被封裝起來(lái)的過程,它駐留在數(shù)據(jù)庫(kù)中,可以被客戶應(yīng)用程序調(diào)用,也可以從另一個(gè)過程或觸發(fā)器調(diào)用。它的參數(shù)可以被傳遞和返回。與應(yīng)用程序中的函數(shù)過程類似,存儲(chǔ)過程可以通過名字來(lái)調(diào)用,而且它們同樣有輸入?yún)?shù)和輸出參數(shù)。
根據(jù)返回值類型的不同,我們可以將存儲(chǔ)過程分為三類:返回記錄集的存儲(chǔ)過程,返回?cái)?shù)值的存儲(chǔ)過程(也可以稱為標(biāo)量存儲(chǔ)過程),以及行為存儲(chǔ)過程。顧名思義,返回記錄集的存儲(chǔ)過程的執(zhí)行結(jié)果是一個(gè)記錄集,典型的例子是從數(shù)據(jù)庫(kù)中檢索出符合某一個(gè)或幾個(gè)條件的記錄;返回?cái)?shù)值的存儲(chǔ)過程執(zhí)行完以后返回一個(gè)值,例如在數(shù)據(jù)庫(kù)中執(zhí)行一個(gè)有返回值的函數(shù)或命令;最后,行為存儲(chǔ)過程僅僅是用來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)的某個(gè)功能,而沒有返回值,例如在數(shù)據(jù)庫(kù)中的更新和刪除操作。
使用存儲(chǔ)過程的好處
相對(duì)于直接使用SQL語(yǔ)句,在應(yīng)用程序中直接調(diào)用存儲(chǔ)過程有以下好處:
(1)減少網(wǎng)絡(luò)通信量。調(diào)用一個(gè)行數(shù)不多的存儲(chǔ)過程與直接調(diào)用SQL語(yǔ)句的網(wǎng)絡(luò)通信量可能不會(huì)有很大的差別,可是如果存儲(chǔ)過程包含上百行SQL語(yǔ)句,那么其性能絕對(duì)比一條一條的調(diào)用SQL語(yǔ)句要高得多。
(2)執(zhí)行速度更快。有兩個(gè)原因:首先,在存儲(chǔ)過程創(chuàng)建的時(shí)候,數(shù)據(jù)庫(kù)已經(jīng)對(duì)其進(jìn)行了一次解析和優(yōu)化。其次,存儲(chǔ)過程一旦執(zhí)行,在內(nèi)存中就會(huì)保留一份這個(gè)存儲(chǔ)過程,這樣下次再執(zhí)行同樣的存儲(chǔ)過程時(shí),可以從內(nèi)存中直接調(diào)用。
(3)更強(qiáng)的適應(yīng)性:由于存儲(chǔ)過程對(duì)數(shù)據(jù)庫(kù)的訪問是通過存儲(chǔ)過程來(lái)進(jìn)行的,因此數(shù)據(jù)庫(kù)開發(fā)人員可以在不改動(dòng)存儲(chǔ)過程接口的情況下對(duì)數(shù)據(jù)庫(kù)進(jìn)行任何改動(dòng),而這些改動(dòng)不會(huì)對(duì)應(yīng)用程序造成影響。
(4) 布式工作:應(yīng)用程序和數(shù)據(jù)庫(kù)的編碼工作可以分別獨(dú)立進(jìn)行,而不會(huì)相互壓制。
優(yōu)點(diǎn):
1.由于應(yīng)用程序隨著時(shí)間推移會(huì)不斷更改,增刪功能,T-SQL過程代碼會(huì)變得更復(fù)雜,StoredProcedure為封裝此代碼提供了一個(gè)替換位置。
2.執(zhí)行計(jì)劃(存儲(chǔ)過程在首次運(yùn)行時(shí)將被編譯,這將產(chǎn)生一個(gè)執(zhí)行計(jì)劃-- 實(shí)際上是 Microsoft SQL Server為在存儲(chǔ)過程中獲取由 T-SQL 指定的結(jié)果而必須采取的步驟的記錄。)緩存改善性能。
........但sql server新版本,執(zhí)行計(jì)劃已針對(duì)所有 T-SQL 批處理進(jìn)行了緩存,而不管它們是否在存儲(chǔ)過程中,所以沒比較優(yōu)勢(shì)了。
3.存儲(chǔ)過程可以用于降低網(wǎng)絡(luò)流量,存儲(chǔ)過程代碼直接存儲(chǔ)于數(shù)據(jù)庫(kù)中,所以不會(huì)產(chǎn)生大量T-sql語(yǔ)句的代碼流量。
4.使用存儲(chǔ)過程使您能夠增強(qiáng)對(duì)執(zhí)行計(jì)劃的重復(fù)使用,由此可以通過使用遠(yuǎn)程過程調(diào)用 (RPC) 處理服務(wù)器上的存儲(chǔ)過程而提高性能。RPC 封裝參數(shù)和調(diào)用服務(wù)器端過程的方式使引擎能夠輕松地找到匹配的執(zhí)行計(jì)劃,并只需插入更新的參數(shù)值。
5.可維護(hù)性高,更新存儲(chǔ)過程通常比更改、測(cè)試以及重新部署程序集需要較少的時(shí)間和精力。
6.代碼精簡(jiǎn)一致,一個(gè)存儲(chǔ)過程可以用于應(yīng)用程序代碼的不同位置。
7.更好的版本控制,通過使用 Microsoft Visual SourceSafe 或某個(gè)其他源代碼控制工具,您可以輕松地恢復(fù)到或引用舊版本的存儲(chǔ)過程。
8.增強(qiáng)安全性:
a、通過向用戶授予對(duì)存儲(chǔ)過程(而不是基于表)的訪問權(quán)限,它們可以提供對(duì)特定數(shù)據(jù)的訪問;
b、提高代碼安全,防止 SQL注入(但未徹底解決,例如,將數(shù)據(jù)操作語(yǔ)言--DML,附加到輸入?yún)?shù));
c、SqlParameter 類指定存儲(chǔ)過程參數(shù)的數(shù)據(jù)類型,作為深層次防御性策略的一部分,可以驗(yàn)證用戶提供的值類型(但也不是萬(wàn)無(wú)一失,還是應(yīng)該傳遞至數(shù)據(jù)庫(kù)前得到附加驗(yàn)證)。
缺點(diǎn):
1.如果更改范圍大到需要對(duì)輸入存儲(chǔ)過程的參數(shù)進(jìn)行更改,或者要更改由其返回的數(shù)據(jù),則您仍需要更新程序集中的代碼以添加參數(shù)、更新 GetValue() 調(diào)用,等等,這時(shí)候估計(jì)比較繁瑣了。
2.可移植性差
由于存儲(chǔ)過程將應(yīng)用程序綁定到 SQL Server,因此使用存儲(chǔ)過程封裝業(yè)務(wù)邏輯將限制應(yīng)用程序的可移植性。如果應(yīng)用程序的可移植性在您的環(huán)境中非常重要,則將業(yè)務(wù)邏輯封裝在不特定于 RDBMS 的中間層中可能是一個(gè)更佳的選擇。
區(qū)別一,存儲(chǔ)過程保存在數(shù)據(jù)庫(kù)里面,存儲(chǔ)過程可以被連接此數(shù)據(jù)庫(kù)的所有程序設(shè)計(jì)語(yǔ)言和程序使用,自定義函數(shù)不能。
區(qū)別二,存儲(chǔ)過程可以有數(shù)據(jù)庫(kù)管理軟件修改,使得多層結(jié)構(gòu)程序調(diào)整系統(tǒng)邏輯時(shí),并不需要編譯和分發(fā)程序。
區(qū)別三,存儲(chǔ)過程執(zhí)行中,不會(huì)引起網(wǎng)絡(luò)流量,不占用程序服務(wù)器的內(nèi)存和CPU資源。
本文來(lái)自CSDN博客,原文地址:http://blog.csdn.NET/defonds/archive/2009/07/15/4349922.aspx
轉(zhuǎn)載于:https://www.cnblogs.com/littlewu/p/5949127.html
總結(jié)
以上是生活随笔為你收集整理的存储过程的优缺点 (转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [大数据之Spark]——Actions
- 下一篇: 个人学习某个系统或平台的3问式的整理和细