前兩天在知乎逛街,看到有這麼個話題,順手回答了下,並分享在這裏,喜歡的話就一塊兒討論討論吧。前端
幾千行的 SQL 存儲過程,在比較老式的開發架構中常見,起源於 C/S 年代。一般是前端沒有引入適當框架的設計,而將全部的應用邏輯一古腦兒丟給數據庫開發形成的。固然這類設計的好處是上線快速,極短期即可拿下項目。而弊端是擴展起來麻煩,尤爲數據庫開發一旦跳槽以後,留下的每每是看不懂的上古祖傳代碼,此時再動刀擴展系統架構去支撐業務需求,就顯得吃力。程序員
做爲負責的數據庫開發,拿到這大幾千行的 SQL 代碼,確定是不能聽之任之的。數據庫
首先,理解代碼。架構
越長的 SQL 越是要理解透徹。開發爲了省事(項目負責人好好反省)憑着腦殼想到哪裏,寫到哪裏,沒有通盤考慮邏輯的合理性與程序的可讀性。有時候明明能夠用一句 update 完成的操做,有些開發笨拙的拆開了不少次去操做,緣由極可能是爲了去記 log, 或者多個條件不懂得去歸併。前者是設計的錯誤,後者是 SQL 本質思想的理解不到位。併發
在動手改代碼以前,必定要理解透徹代碼,不能操之過急。每每像這類耦合度高的 SQL 應用邏輯,好幾個地方都在用,改了以後不必定會給哪裏形成 bug.框架
接着,分拆代碼。優化
在理解透徹業務邏輯的基礎上,對代碼進行整塊的分拆和聚合。分拆和聚合的關鍵是控制事務。主表一級的事務,子表一級的事務,是否是能夠分開處理,仍是必須聯合處理。是否考慮用多個子存儲過程來格式化代碼,顯得更加易讀,邏輯上也更加易懂。編碼
分拆代碼的好處是可讓你快速掌握業務邏輯,熟絡每一個業務關鍵點,重點是培養對業務的敏感。設計
再接着,改寫代碼。3d
當已經把代碼段落按照業務邏輯分拆,合併以後,接下來就是在 SQL 細節層面作優化。這時候首先要考慮 SQL 語言的特色,集合化思想。若是你有魔方,能夠拿起來看下,SQL 處理的是面以及面與面之間的關係。
若是要把紅色的方塊都選中,有的開發朋友會將第 1, 2,3 行的篩選條件單獨拿出來,各自選出來以後再塞到臨時表去作聚合,而正確的作法是將 1, 2, 3 的篩選條件首先聚合,歸併,使用一條 SELECT 或 Update 語句完成本來冗餘的代碼。
在命名規範,Magic Number,低效率 SQL 編碼上都要作嚴格審查,防止代碼的腐化。很差的 SQL 代碼習慣看到不少,直接寫 insert ... select * from /update/delete 都是要嚴格禁止的;在大併發的系統中,使用臨時表裝載大量數據來知足報表需求,也是要適可而止的;OLTP 要和 OLAP 嚴格分開庫,這種並存一庫的架構至今在不少單位還存在着。
最後,保存代碼。
任何代碼都須要進 Source Code Version Control. 不管是 Git/SVC/TFS, 針對遺留代碼,新增代碼都要進行完整的源代碼版本控制,作到有源可溯。
爲何會有這大幾千行的 SQL 代碼呢,我猜緣由有 2 :
1 項目趕,時間緊,一切 以上線爲重。自覺得上線後會修改本身的代碼,每每不大可能。就算你有心,後面的項目需求也會把你的積極性消磨殆盡。一旦項目結束,你跳槽,薪水翻倍了,再回頭就沒有機會了。
2 寫 SQL 不寫草稿。這個習慣可能大部分人都會以爲很奇怪,寫代碼還寫草稿?其實代碼和寫做同樣,都是一種表達。村上春樹寫小說都打草稿,還修改不止一兩遍。博爾赫斯等大文豪,對於修改是很是執着的。沒有四五遍修改,都很差意思見人。咱們有些程序員就是太貪,太急,潦草完事,從不往回找找感受。看到業務就想接,這樣不是很差,但總結概括本就是一門提升效率的學問,觸類旁通手藝才能穩步提升。
有多少朋友,Pivot 老是寫得不順手,歸根結底就是對寫過的代碼不總結,而寫草稿,偏偏給你一個總結的過程。