程式設計師過關斬將--小小的分頁引發的加班血案

架構師修行之路發表於2019-05-13

菜菜哥,我又來了

晚上請我喝咖啡嗎?

那你得先幫我解決一個問題

說來聽聽

昨天加班很晚排查一個分頁引起的問題,到現在還沒解決,心情有點抑鬱,需要安慰

說來聽聽

我們新做的商城首頁是一個分頁的商品的列表,昨天運營反應,載入出來的商品偶爾有重複的,但是我本地和測試伺服器都沒問題,程式碼是沒問題的

分頁是怎麼寫的呢?

就是傳統的那種,客戶端上傳pagesize和pageindex兩個引數,然後服務端根據排序規則去排序

那我可能知道怎麼回事了,晚上咖啡我喝定了

問題分析

        通過以上的對話,身為程式設計師的你是否也遇到過妹子這樣的問題呢?傳統的而且網上到處充斥著的也是這類方式,客戶端根據自己的滾動不斷的更新pagesize和pageindex兩個引數,然後上傳給服務端介面獲取資料,而且網路上也很少說明這種方式是否有問題,那到底有沒有問題呢?

    談到分頁,無論程式怎樣寫,分頁這個業務的核心動作是根據開始位置和結束位置來獲取一段資料,無論你的排序規則有多複雜,最終的目的總是獲取總列表資料中一段連續的資料。無論你是直接用的sql語句分頁,還用的搜尋引擎(比如es),最終在客戶端體現的效果就是下一頁的資料展現。

當然體現在客戶端的UI上的互動操作可以有很多樣式


如果是瀑布流或者app段滾動展示的方式,或者其他不需要資料總個數的情況下,菜菜認為服務端千萬不要查詢這個總個數資料,展示方完全可以以下一頁有無資料作為是否繼續拉取下一頁資料的依據。


話題迴歸,如果客戶端依據pagesize和pageindex引數來進行分頁需求,有沒有問題呢?當然有,要不然菜菜寫這篇文章意義何在,我又不是一個喜歡愛扯淡的程式設計師~~

問題所在

這裡以最簡單也是最基本的sql 語句分頁為例,假如現在資料庫現有資料為

1,2,3,4,5,6,7

排序的規則是按照大小倒序,即資料的全部列表為:

7,6,5,4,3,2,1

假如現在是獲取第二頁資料,pagesize為2,pageindex為2,正確結果為 “5,4”   。這無可厚非,在資料未發生改變的情況下,正確結果確實如此,那如果資料發生的變化呢,假如現在新加入一條資料 8,列表資料會變為

8,7,6,5,4,3,2,1

那依據以上分頁原則,第二頁獲取的資料就變為了“6,5”,聰明的你是不是發現了問題,這也可能是D妹子引發加班的原因。

分頁的操作是建立在動態資料上的操作


解決問題

分頁操作的資料來源是動態變動的,有時候變動的部分正好發生在你獲取的資料範圍內,就會發生資料重複或者錯誤的情況。那怎麼解決呢?

客戶端

作為資料的需求方和展示方,客戶端需要記住已經載入的資料的主鍵列表,如果某條資料已經展示過,根據業務需求來確定是否要重複展示,一般情況下需要去重。


如果資料量非常大,客戶端維護一個資料池的方案其實也不夠理想

服務端

1. 服務端分頁介面引數新增上一頁最後一條資料id引數lastId,去掉pageindex引數,因為在多數情況下,pageindex引數在服務端的作用是確定資料的起點而已,如果有了lastid,pageinde在很多情況下其實已經不需要了。

2. 服務端把所有的資料做快取,這樣動態資料在一定時間內靜態化,但是這樣也是治標不治本。

3. 如果業務上對於排序無要求的話,服務端可以採用順序分頁,把獲取的資料落在不會變動的資料段上


服務端要想把動態的資料搞成靜態有點難度


業務方

無論程式怎麼優化也改變不了資料是在不停變動的本質,如果業務方(產品,運營)能夠接受資料在偶爾情況下能重複的現象,那能大幅度減少程式設計師的工作了。

有時候你認為的資料bug,在其他業務部門不一定是什麼重大問題。

THE END


程式設計師修神之路--問世間非同步為何物?
程式設計師修神之路--提高網站的吞吐量?
程式設計師修神之路--?分散式高併發下Actor模型如此優秀?
程式設計師過關斬將--論商品促銷程式碼的優雅性
程式設計師過關斬將--請不要隨便修改基類
程式設計師過關斬將--你的面向介面程式設計一定對嗎?
程式設計師修神之路--高併發下為什麼更喜歡程式內快取
程式設計師修神之路--高併發優雅的做限流


相關文章