菜菜哥,我又來了程序員
晚上請我喝咖啡嗎?web
那你得先幫我解決一個問題sql
說來聽聽數據庫
昨天加班很晚排查一個分頁引發的問題,到如今還沒解決,心情有點抑鬱,須要安慰編程
說來聽聽緩存
咱們新作的商城首頁是一個分頁的商品的列表,昨天運營反應,加載出來的商品偶爾有重複的,可是我本地和測試服務器都沒問題,代碼是沒問題的服務器
分頁是怎麼寫的呢?網絡
就是傳統的那種,客戶端上傳pagesize和pageindex兩個參數,而後服務端根據排序規則去排序併發
那我可能知道怎麼回事了,晚上咖啡我喝定了app
問題分析
經過以上的對話,身爲程序員的你是否也遇到過妹子這樣的問題呢?傳統的並且網上處處充斥着的也是這類方式,客戶端根據本身的滾動不斷的更新pagesize和pageindex兩個參數,而後上傳給服務端接口獲取數據,並且網絡上也不多說明這種方式是否有問題,那到底有沒有問題呢?
談到分頁,不管程序怎樣寫,分頁這個業務的核心動做是根據開始位置和結束位置來獲取一段數據,不管你的排序規則有多複雜,最終的目的老是獲取總列表數據中一段連續的數據。不管你是直接用的sql語句分頁,還用的搜索引擎(好比es),最終在客戶端體現的效果就是下一頁的數據展示。
固然體如今客戶端的UI上的交互操做能夠有不少樣式
話題迴歸,若是客戶端依據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,在其餘業務部門不必定是什麼重大問題。