5000 行的 SQL 源代碼,怎么讀?
本文轉(zhuǎn)載自微信公眾號(hào)「有關(guān)SQL」,作者有關(guān)SQL。轉(zhuǎn)載本文請(qǐng)聯(lián)系有關(guān)SQL公眾號(hào)。
今天的小 C 很不在狀態(tài)。昔日的她,一大早肯定不會(huì)愁容滿面,似乎像是星巴巴沒有喝夠的樣子,興奮不起來!11:30 了,很少聽到她 HHKB 落鍵的清脆聲,一定是遇到難題了!
“怎么,今天的熱焦瑪少了點(diǎn)勁兒嘛,感覺?”我走近了小 C。
“L, 面對(duì)著滿屏的 SQL,誰都會(huì)提不起精神啊。何況這近 5000 行的代碼,怎么看得過來嘛!看了中間忘了開頭,看到結(jié)尾,前面的全忘光了,好煩呀” 小姑娘抱怨起來也是毫不拖泥帶水。
“喲,恭喜你,遇到這么極品的 sp 啊。在我的印象里面,經(jīng)歷了兩次重構(gòu)之后,上千行的代碼,就那么幾個(gè),今天被你遇到了。我看看是哪個(gè)”
“原本我以為很簡(jiǎn)單的一個(gè) AddUpdate, 誰想邏輯這么復(fù)雜,牽扯的表也太多了,其中幾個(gè)表還有上百個(gè)字段,這都沒法看了” 小 C 的鼠標(biāo)滿屏的亂走,看得我 300 度的眼睛,有些吃力。
“你這一行一個(gè)字段,是你自己設(shè)置的吧,其實(shí)不需要那么格式化,反而更簡(jiǎn)單。你看啊,一個(gè) Insert 被幾十個(gè)字段隔成了兩屏,容易造成思維停頓。兩行搞定的事情,做復(fù)雜了。還顯得代碼量大,失去耐心。”
“那我還原成原先的格式,也有近 3000 多行,還是多啊”
“這閱讀源代碼啊,是有技巧的。我可以分享三點(diǎn)給你。分別是,通讀,聯(lián)想,批評(píng)。”
“第一點(diǎn),通讀,非技術(shù)性的通讀。首先告訴自己,一遍讀完就能通曉5000行代碼細(xì)節(jié),是不可能的事情。讀代碼前,耐心先行。接著就是開始第一遍的閱讀。此時(shí)的代碼走讀,我們不停留在具體的技術(shù)末節(jié)上,比如 unpivot 的語法是怎么樣實(shí)現(xiàn)的,為什么有里三層外三層的嵌套,為什么這里用了動(dòng)態(tài) SQL 去拼接。再比如,XML 的節(jié)點(diǎn)鋪設(shè),為什么要這么定義,共有多少層。這些留在最后。”
“我們?cè)谧咦x代碼的時(shí)候,尤其是第一遍,首先要理清的是業(yè)務(wù)的數(shù)據(jù)流,比如訂單是如何觸發(fā)的,分別涉及到哪些主體,人,物,財(cái),時(shí)間。知道這些數(shù)據(jù)流分別存在哪些表里,存儲(chǔ)的先后順序是什么,會(huì)記錄哪些日志。我們的 sp 邏輯結(jié)構(gòu)相對(duì)簡(jiǎn)單,一個(gè)事務(wù)一個(gè)存儲(chǔ)過程。所以第一遍,通讀,越快了解所有涉及到的業(yè)務(wù)過程,最重要。你也可以在手邊,畫畫流程圖,幫助記憶。”
看著小 C 若有所思的眼神,分明能感覺到她腦子里抽象的擰巴,因此順手我畫了一張上面的流程圖。“第一遍走讀代碼,你能清晰的畫出類似上面的圖,知道這些數(shù)據(jù)存在哪里,就足夠了。”
“嗯,原來是這樣,難怪我老是連接不起來,看過了,腦子里留不下印象!那第二點(diǎn)呢?”
“第二點(diǎn),需要聯(lián)想,也就是想象力。看完第一遍,不要急著看第二遍,就在腦子里,回想第一遍的過程。把你認(rèn)為創(chuàng)建一個(gè)訂單需要記錄的信息給標(biāo)出來,盡可能詳細(xì)的在流程圖上標(biāo)準(zhǔn)細(xì)節(jié),就好比人,在什么時(shí)候需要記錄人的信息,需要檢驗(yàn)人的信息;再比如貨,什么時(shí)間段,要檢查貨的庫(kù)存,要記錄貨的哪些屬性,單價(jià)還是 SKU,怎么更新貨的庫(kù)存,更新失敗了怎么辦?”
“如果你看到長(zhǎng)篇的 SQL ,還只停留在腦子里,不靠譜。工作記憶永遠(yuǎn)只有 15 分鐘。讀完一遍后,你被叫去開個(gè)會(huì),回來你就可能記不清了。所以及時(shí)的傾倒出來你剛才讀到的 SQL,多問問自己數(shù)據(jù)是怎么流轉(zhuǎn)下來的,畫好流程圖,標(biāo)準(zhǔn)自己的想法,越清晰,問題越多,越有利下一遍的閱讀...”
"我知道了,我知道了,就是帶著問題,主動(dòng)去尋找答案!"
“理解到位,就是這樣。給自己找問題,千萬別一遍看完代碼,什么都沒留下來。接著,你可以去閱讀第二遍,第三遍,甚至是第四遍了”
"那還有第三點(diǎn)呢?" 小 C 似乎來勁了。
“第三點(diǎn)最重要,批評(píng)。如果你對(duì)讀到的代碼,沒有任何要抱怨,沒有任何疑惑,那說明還沒理解到位。當(dāng)你看到這些代碼,你認(rèn)為嗯,這段寫的很好,這段寫的在理,都是這些溢美之詞,那完了,你沒深入。你可能對(duì) unpivot , cross apply, openXML, OffSet 讀到真正實(shí)戰(zhàn)版代碼而感到興奮,覺得這段 sp 就寫的很好,那對(duì) SQL 的認(rèn)識(shí)就太膚淺了。”
“新聞界,會(huì)有很多評(píng)論家,對(duì)重大新聞做二次剖析,比如曹林,《時(shí)評(píng)寫作十講》的作者,擅長(zhǎng)對(duì)每篇新聞做雙面解析。既講述原新聞作者的報(bào)道手法,也評(píng)價(jià)原作者的目的與動(dòng)機(jī),最后還補(bǔ)充自己的觀點(diǎn),非常有意思。”
“在我們編程這個(gè)圈子,也有很多書,專講這方面的。我給你推薦幾本吧,《編程珠璣》,《CLR Via C#》, 尤其是 SQL 數(shù)據(jù)庫(kù)方面,《數(shù)據(jù)庫(kù)索引設(shè)計(jì)與優(yōu)化》,《Oracle 優(yōu)化日記》,《T-SQL Querying》,《T-SQL 性能調(diào)優(yōu)秘籍-基于SQL Server 2012 窗口函數(shù)》”
“這些書,非常基礎(chǔ),我自己看過不止一遍。可以快速幫你提高內(nèi)功。且,書的優(yōu)點(diǎn)在于,作者就像是代碼評(píng)論家一樣,告訴你為什么 SQL或者代碼這么寫,不如那樣寫來的高效,其中的原理是什么。這些都是你在分析具體代碼時(shí),可以學(xué)到的真正有用的東西。我們應(yīng)該在任何一段 SQL 中都找到可以學(xué)習(xí)的地方,最好是找到這段代碼的設(shè)計(jì)弱點(diǎn),比如子查詢嵌套太多,不簡(jiǎn)潔;比如篩選條件不夠優(yōu)化,需要代碼重構(gòu),這就是第三點(diǎn),批評(píng)的實(shí)質(zhì)。”
“又推薦書啊,上次推薦的還沒看完。”
“書在用時(shí),方恨少。”