儲存過程的優缺點個人總結
公司的系統是自主開發的,歷史比較悠久,有不少是傳統C/S架構,採用儲存過程來處理業務邏輯。
近來做新系統的時候,我採用了三層架構,拋棄儲存過程改用ORM。
有同事問及不用儲存過程的理由,我想了一下,對儲存過程做了如下總結。
本人經驗和水平有限,總結有所偏頗,還請大家糾察。
優點
1.在生產環境下,可以通過直接修改儲存過程的方式修改業務邏輯(或bug),而不用重啟伺服器。但這一點便利被許多人濫用了。有人直接就在正式伺服器上修改儲存過程,而沒有經過完整的測試,後果非常嚴重。
2.執行速度快。儲存過程經過編譯之後會比單獨一條一條執行要快。但這個效率真是沒太大影響。如果是要做大資料量的匯入、同步,我們可以用其它手段。
3.減少網路傳輸。儲存過程直接就在資料庫伺服器上跑,所有的資料訪問都在伺服器內部進行,不需要傳輸資料到其它終端。但我們的應付伺服器通常與資料庫是在同一內網,大資料的訪問的瓶頸會是硬碟的速度,而不是網速。
4.能夠解決presentation與資料之間的差異,說得文藝青年點就是解決OO模型與二維資料持久化之間的阻抗。領域模型和資料模型的設計可能不是同一個人(一個是SA,另一個是DBA),兩者的分歧可能會很大——這不奇怪,一個是以OO的思想來設計,一個是結構化的資料來設計,大家互不妥協——你說為了軟體的彈性必須這麼設計,他說為了效率必須那樣設計,為了抹平鴻溝,就用儲存過程來做資料儲存的邏輯對映(把屬性對映到欄位)。好吧,臺下已經有同學在叨咕ORM了。
5.方便DBA優化。所有的SQL集中在一個地方,DBA會很高興。這一點算是ORM的軟肋。不過按照CQRS框架的思想,查詢是用儲存過程還是ORM,還真不是問題——DBA對資料庫的優化,ORM一樣會受益。況且放在ORM中還能用二級快取,有些時候效率還會更高。
缺點
1.SQL本身是一種結構化查詢語言,加上了一些控制(賦值、迴圈和異常處理等),但不是OO的,本質上還是過程化的,面對複雜的業務邏輯,過程化的處理會很吃力。這一點算致命傷。
2.不便於除錯。基本上沒有較好的偵錯程式,很多時候是用print來除錯,但用這種方法除錯長達數百行的儲存過程簡直是噩夢。好吧,這一點不算啥,C#/java一樣能寫出噩夢般的程式碼。
3.沒辦法應用快取。雖然有全域性臨時表之類的方法可以做快取,但同樣加重了資料庫的負擔。如果快取併發嚴重,經常要加鎖,那效率實在堪憂。
4.無法適應資料庫的切割(水平或垂直切割)。資料庫切割之後,儲存過程並不清楚資料儲存在哪個資料庫中。
5.精通SQL的新手越來越少——不要笑,這是真的,我面試過N多新人,都不知道如何建立全域性臨時表、不知道having、不知道聚集索引和非聚集索引,更別提遊標和提交叉表查詢了。好吧,這個缺點算是湊數用的,作為屌絲程式設計師,我們的口號是:沒有不會的,只有不用的。除了少數有語言潔癖的人,我相信精通SQL只是時間問題。
總結
儲存過程最大的優點是部署的方便性——可以在生產環境下直接修改——雖然濫用的後果很嚴重。
儲存過程最大的缺點是SQL語言本身的侷限性——我們不應該用儲存過程處理複雜的業務邏輯——讓SQL迴歸它“結構化查詢語言”的功用吧。