存儲過程用還是不用?我有話說!

Java技術棧

www.javastack.cn

關注閱讀更多優質文章

很多朋友習慣以阿里禁止使用存儲過程,來鼓吹項目中不該使用它。

我想問的是,阿里那幫程序員,爲了不用存儲過程,做過的那些努力,你看到了嗎?在去 SP 的過程中,所使用的技術與編程模式,你會嗎?

SP: Stored Procedure. 即存儲過程

人云己不亦云,一直是我對自己的要求。

程序員的獨立思考習慣,與其他行業從業人員相比,我認爲一直佔據上風。出現其他行業“羣氓”的慣性思維,概率很低。這是一幫只認 0 和 1 的清醒思考份子。他們誰都不信,只相信自己經手的代碼和邏輯。

該不該用存儲過程,取決於很多因素。有項目本身因素,也有人員配置因素。

拋開項目說策略,就跟不以結婚爲目的的談戀愛一樣。一個簡單的匿名留言板,用貴上天的 Oracle 幹嗎,用 MongoDB,用 ElasticSearch,甚至用 Redis,不香嘛!

對信息系統理解不全面,腦袋裏只有 OLTP 系統, 眼裏只有 CRUD  一類的 M-I-O 應用,那麼自然會覺得存儲過程沒有用的必要。用 Java, PHP 完全能勝任數據一進一出的功能。甚至能做得更好。

比如在遷移數據庫的時候,在更換數據庫軟件的時候,只需在前端的 Helper, Utility 類中,更改下數據庫驅動和連接,即可實現無縫轉換。假如此時要把存儲過程從 SQL Server 遷移到 Oracle 上,那必然得重招一批數據庫開發。成本巨大,且不宜長久的事,哪家公司會做這樣的好人?

再比如,在對接異構分佈式數據庫的時候,由前端語言接口,封裝好對數據庫的訪問以及路由,就能自動承接各數據庫來的各類型數據結構。關係型也好,半關係型,甚至離散數據,都能友好地組織起來。要用存儲過程來實現,那必然要在數據庫動態庫上編程,使其適應各類平臺的連接,參考 SQL Server HDInsight 對接 Spark 引擎的實現。

顯然,動態鏈接庫增加了數據庫的複雜性和脆弱性,且不如前端實現,那麼靈活與可擴展。寫一個連接服務,部署到 10 臺應用服務器中,就能扛起 10 倍的流量。而寫一個動態鏈接庫,放一臺數據庫服務器中,撐起的流量不變。

OLTP: Online Transaction Processing, 在線交易系統, 在線事務處理系統

CRUD:Create Retrieve Update Delete 即增刪改查

M-I-O: Message IN And Out 消息輸入輸出

看到這,似乎沒有一條有利於存儲過程的存在。那是不是小編我就鼓吹不用存儲過程了呢?我把開頭的話,再講一遍,拋開項目說策略,就跟不以結婚爲目的的談戀愛一樣

時刻保持腦子可以清醒思考,是程序員的重要素質

除了 OLTP,這世界上還有一種叫做 OLAP 的應用。OLTP 系統運行多年後,承載了大量的用戶數據,訂單數據,行爲數據。像用戶畫像,漏斗分析,運營決策這樣的應用,大家耳朵上的繭子都聽得長厚了。

這些需求一旦展開,往往牽扯到跨時長達3,5年的查詢,數據量巨大,引起大量 CPU, Memory,IO   的開銷,足夠摧毀正常業務操作。說人話,一張報表拖死一個應用,常有的事兒。

OLAP 技術便應運而生,除了要給足這些應用硬件資源,還要搭配一些軟件設計模式。在這個成熟的 OLAP 領域,不得不提 Kimball 和 Inmon 的維度建模思維和實戰。廣爲大家所知的,便是 ETL ,Reporting 和 Data Modelling. 在整個數據管道的過程中,如果計算下聚合,都要跑前臺應用程序過一遍,那麼數據的流入流出,就已經花費極大的寬帶流量和時間了。所以落地這些大型計算和存儲,必定要存儲過程來承擔。

可能大家都知道,就連 Hadoop/Spark 都強調數據本地性的調優法則。這大概正是從數據庫的存儲過程中得到的啓發。

OLAP: Online Analysis Processing, 在線分析處理

存儲過程將會在很長一段時間內,繼續佔據商業數據庫應用市場。但 NoSQL 以及分佈式大數據平臺 (可看成 NewSQL)這支力量,也不可小覷。很多應用不再以數據庫爲中心,更多采用去中心化設計。

比如以往記錄日誌,會選擇以數據庫爲存儲,不僅耗費大量昂貴的數據庫存儲空間,還加大數據庫的開銷。自從 MongoDB,ElasticSearch 出現之後,日誌類文件最佳使用方法,便是記錄到這些 NewSQL 數據庫中。

這些數據庫不僅僅以廉價的機器作爲存儲,更可以負擔一些以往落在數據庫上的操作。並且,這些系統出現時,就瞄準了傳統商業數據庫難以水平擴展的難題,他們的架構使得水平擴展集羣性能變得容易。

配以這幅圖,這肯定不難理解。

當中央數據庫被劃分爲 5 大地區數據庫後,服務能力提升是明顯的。但傳統數據庫就沒有這麼好的擴展性。所以各家數據庫服務商拼命地都往雲上趕,就是這個道理。雲服務擴展的便利,簡單得令人髮指,千百臺機器,點擊便可完成。前提當然是,甲方爸爸非常有錢。

那麼,存儲過程在這個時候,就不得不讓位於分佈式編程。如果寫SQL的朋友,一直不往其他領域擴展,等到有大數據分佈式相關項目的時候,就只能眼睜睜看着機會溜走。豈不可惜?

但,是不是這些 NoSQL,NewSQL 能直接取代傳統數據庫了呢,並不是。舉個例子,他們現階段難以掌控的事務控制,像MongoDB, ElasticSearch,事務控制加在了文檔一層,單個文檔可以保證ACID,但多個文檔就需要程序員自己控制。像Redis這樣的緩存級數據層,在多表聚合這類操作上,還要大大依賴前端開發人員的編程實現。

即使有程序庫可以完成這些操作,那也將是類存儲過程的這種實現,像MongoDB用 JavaScript 模板。那麼爲什麼要放棄團隊中會存儲過程,這種已經熟得不能再熟的技術呢?這不是每個程序員必會的技能麼。

程序本質上是人類思考的結果,無論用存儲過程還是Java,PHP前端語言(與數據庫後端相比,其他語言都可劃爲前端),我們完成的始終是業務的計算。那麼自然是哪個方便,用哪個;哪個最有效率,用哪個。

與其糾結於用什麼實現業務邏輯,倒不如考慮業務複雜度和團隊協作便利性。如果有全棧工程師,從前到後,都可以玩得來,那麼就讓他快速迭代產品。如果前端工程師對數據庫有認識上的偏差,對於調優和事務不能很好控制,又或者項目緊張,一個全棧工程師忙不過來,那麼就把前端和後端獨立開來,招兩端各自優秀的工程師,各司其職就好。

但無論怎麼樣,我們最好前後及後都懂些,然後選一個精通。這可以完美避免,互相指着鼻子罵對方是豬隊友的尷尬情況。

:除了數據庫, 其他都可稱前端;

:存儲基礎業務庫的數據庫端;

及後的後:服務 OLAP 的數據平臺,即包括數據庫,還有分佈式大數據平臺。

最近熱文:

1、Tomcat 又爆出高危漏洞!8.5 ~ 10 中招…

2、Spring Boot 幹掉了 Maven 擁抱 Gradle!

3、打破你的認知,數字除以0一定會崩潰嗎?

4、寫了個全局變量的bug,被同事們打臉!

5、Java 14 祭出神器,Lombok 被幹掉了?

6、爲什麼 Redis 單線程能達到百萬+QPS?

7、Spring Boot 2.3 優雅關閉新姿勢,真香!

8、玩大發了,Tomcat 8.5 升級有坑…

9、我天!xx.equals(null) 是什麼騷操作??

10、Spring Boot 2.3.1 發佈, 10 個新特性!

掃碼關注Java技術棧公衆號閱讀更多幹貨。

點擊「閱讀原文」獲取面試題大全~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章