「預存程序是邪惡的」
「已經過時了」
在談論資料庫設計或應用程式設計時,我們經常聽到這樣的聲音。
這次調查這個背景時,我想到了一些過去的現場經驗,因此決定撰寫這篇文章。
本文將整理以下幾個要點:
・為什麼預存程序會誕生
・為什麼最近會變得不受歡迎
・與當前的主流設計之間的關係
預存程序的誕生是為了將處理集中在資料庫端。
當時的主要目的如下:
如果應用程式重複執行
SQL發送→接收結果→再發送SQL
的往返過程,網路成本會很高。
透過預存程序的設計,可以在一次呼叫中完成一系列處理。
這一點確實如此,我在現場也曾經使用預存程序使得應用的處理性能提升了五倍、六倍。
多年來進行性能改善的經驗告訴我,除非SQL質量相當糟糕,否則重新檢視SQL的效果往往不如減少通信次數來得明顯,數十倍到數百倍的性能改善的案例非常常見。
在多個應用程式和多個畫面之間重複使用相同的更新處理或聚合處理。
為了確保多個INSERT/UPDATE/DELETE能夠成功或失敗地一起控制,最好在資料庫端進行控制,這樣比較安全。
不允許直接存取表格,並且可以設計授權以便「僅可執行這個程序」。
原因很簡單,因為與現代的開發風格不相容。
以下進行整理:
預存程序有
・每個資料庫的獨特語言
・IDE支持弱
・複雜化後容易造成困難
的問題,這使得其容易成為「只有編寫者能接觸的代碼」,這是最大問題。
這一點我也深有同感。
我曾見過許多過去編寫的長篇預存程序,由於過於雜亂而難以修正,最終只能束手無策,讓現場人員煩惱。
如果讓經驗豐富的工程師來修改預存程序還算好,如果讓對資料庫很了解但對編碼不熟悉的工程師來動手,更可能導致再也沒有人能修正的局面。
應用程式代碼
・使用Git管理
・實現差異檢查
・CI
・Pull Request評審
是理所當然的,但預存程序多直接在資料庫中定義,容易導致運用崩潰。
單元測試難以編寫,
・需要資料庫
・數據準備繁重
・故障時很難進行切割
存在這些問題。
例如T-SQL或PL/SQL,若切換資料庫幾乎需要重新編寫。
※與雲端遷移或多雲環境相容性差。
・應用層:
業務邏輯、控制、驗證
・資料庫:
數據持久化與一致性保障
應用程式與資料庫是
・不同伺服器
・不同可用區
・不同VPC
這樣的前提。
因此,
・不進行不必要的往返
・進行批量獲取
・通過API設計解決
是我們的發展方向。
透過ORM或查詢建構器的進化,
在確保
・安全性
・可讀性
・測試容易性
的同時,現在可以讓應用主導資料庫操作了。
現在仍然有效的場合包括
・大量數據的批量更新
・聚合類批次處理
・需要極端減少通信次數的處理
等。
不過「局部性和限定性地使用」
這是當前現實的立足點。
預存程序並不是因為
・過時而被厭惡
・錯誤用法可能變成地獄的技術
如今的主流是,
應用主導+資料庫簡單
透過設計減少通信,預存程序是「最後的王牌」。
了解成為「被厭惡者」的背景後,可以從設計判斷而非情感論來進行處理。
原文出處:https://qiita.com/gmo-connect-ogawa/items/48f339fcecabf432969f