分頁(yè)接口設(shè)計(jì)

兩種分頁(yè)方式

傳統(tǒng)的分頁(yè)方式頁(yè)最典型的特點(diǎn)是頁(yè)面上有一連串的頁(yè)碼,和電梯按鈕相似,因此頁(yè)常被稱之為電梯式分頁(yè)。

電梯式特點(diǎn):

  • 通過(guò)頁(yè)碼進(jìn)行分頁(yè)
  • 通過(guò)點(diǎn)擊上/下頁(yè)按鈕可實(shí)現(xiàn)頁(yè)面切換
  • 通過(guò)點(diǎn)擊頁(yè)碼可實(shí)現(xiàn)頁(yè)面切換
  • 可直接跳轉(zhuǎn)至指定頁(yè)面
  • 多用于 PC 端,適合需要查找特定內(nèi)容的頁(yè)面
  • 需要計(jì)算總數(shù)or總頁(yè)數(shù)(搜索引擎等場(chǎng)景也可以無(wú)需計(jì)算渴语,相應(yīng)的跳轉(zhuǎn)按鈕會(huì)有所限制)

電梯式分頁(yè)適用于傳統(tǒng)的頁(yè)面布局丁逝,而在移動(dòng)端頁(yè)面上更流行的是瀑布流布局方式汁胆,相應(yīng)的分頁(yè)方式稱為流式分頁(yè),有時(shí)也稱為無(wú)限下拉式分頁(yè)霜幼。

流式分頁(yè)特點(diǎn):

  • 通過(guò)滾動(dòng)/上拉/點(diǎn)擊等方式加載新一頁(yè)
  • 無(wú)頁(yè)碼
  • 無(wú)上/下頁(yè)按鈕
  • 不可跳轉(zhuǎn)至指定頁(yè)面
  • pc端和移動(dòng)端均有使用嫩码,適合UGC、視覺(jué)內(nèi)容以及推薦系統(tǒng)等“瀏覽型”頁(yè)面
  • 無(wú)需計(jì)算總數(shù)or總頁(yè)數(shù)

對(duì)于用電梯式分頁(yè)方式的接口罪既,有頁(yè)碼铸题、頁(yè)大小以及結(jié)果總數(shù)等參數(shù),頁(yè)碼需要明確是從1開(kāi)始還是0開(kāi)始琢感,一般使用pageNumber表示從1開(kāi)始丢间,使用pageIndex表示頁(yè)索引從0開(kāi)始,pageSize和limint均可表示單頁(yè)數(shù)據(jù)量驹针。totalCount和totalPage可以分別表示總數(shù)據(jù)條數(shù)和總頁(yè)數(shù)烘挫。

  • page(pageNumber、pageIndex)
  • pageSize/limit
  • total(totalCount柬甥、totalPage)

當(dāng)然饮六,對(duì)于流式分頁(yè),上述的接口設(shè)計(jì)也滿足要求苛蒲,但在大多數(shù)場(chǎng)景下卤橄,可以使用更適合的設(shè)計(jì),比如游標(biāo)式(下文會(huì)介紹)臂外。

常見(jiàn)問(wèn)題

數(shù)據(jù)缺失:獲取后頁(yè)時(shí)窟扑,前頁(yè)數(shù)據(jù)有刪除。此時(shí)漏健,本應(yīng)出現(xiàn)在后頁(yè)的內(nèi)容被“頂”到前頁(yè)嚎货,而前頁(yè)已經(jīng)加載過(guò)了不會(huì)重新加載,后頁(yè)又無(wú)此內(nèi)容蔫浆,從而無(wú)法被用戶看到殖属。

數(shù)據(jù)重復(fù):獲取后頁(yè)時(shí),前頁(yè)數(shù)據(jù)有插入克懊。此時(shí),原本在前頁(yè)的內(nèi)容被“壓”到后頁(yè)七蜘,導(dǎo)致前后也都有此數(shù)據(jù)谭溉,在用戶端就是重復(fù)數(shù)據(jù)。

性能問(wèn)題:較大頁(yè)碼的數(shù)據(jù)獲取時(shí)性能會(huì)下降橡卤,計(jì)算總數(shù)也會(huì)帶來(lái)額外的開(kāi)銷扮念。

解決方案:

  1. 游標(biāo)式分頁(yè)參數(shù)設(shè)計(jì):
  • 客戶端記錄當(dāng)前分頁(yè)的最后一條數(shù)據(jù)的 ID(curcor)
  • 請(qǐng)求下一頁(yè)的時(shí)候,從這個(gè) ID 開(kāi)始獲取一頁(yè)大斜炭狻(pageSize)的內(nèi)容

優(yōu)點(diǎn):

  • 能夠避免數(shù)據(jù)重復(fù)/遺漏
  • 無(wú)需計(jì)算offset柜与,性能更穩(wěn)定

缺點(diǎn):

  • 只適用于按照時(shí)間追加的方式等簡(jiǎn)單排序
  • 無(wú)法跳到指定頁(yè)巧勤,適合流式分頁(yè)
  1. 一次性下發(fā)或緩存所有ID
  • 請(qǐng)求第 1 頁(yè)數(shù)據(jù)之前/時(shí)先緩存所有 ID 列表
  • 請(qǐng)求第 2,3弄匕,…n 頁(yè)數(shù)據(jù)時(shí)颅悉,只需傳入單頁(yè)相關(guān)的 ID 列表參數(shù)

優(yōu)點(diǎn):

  • 可將排序由數(shù)據(jù)庫(kù)移到應(yīng)用容器,同時(shí)僅取ID一列迁匠,降低DB壓力剩瓶。
  • 無(wú)需重復(fù)計(jì)算總數(shù),性能更優(yōu)更穩(wěn)定城丧。

缺點(diǎn):

  • 僅適用于 id 列表不會(huì)很大(數(shù)百條數(shù)據(jù))的業(yè)務(wù)場(chǎng)景
  1. 限定數(shù)據(jù)生成時(shí)間

分頁(yè)參數(shù)中再額外多一個(gè)timestamp參數(shù)延曙,第一頁(yè)請(qǐng)求時(shí)timestamp由后端生成并傳給前端,前端在后頁(yè)查詢時(shí)將此值再次傳回給后端亡哄,后端在查詢條件中只用此值限定數(shù)據(jù)插入時(shí)間枝缔。

此方法可以解決數(shù)據(jù)重復(fù),但無(wú)法解決數(shù)據(jù)缺失蚊惯,因此適用于只增不刪或極少刪的場(chǎng)景愿卸。

常見(jiàn)性能問(wèn)題優(yōu)化方法

  1. SQL查兩次,先查出所需頁(yè)的ID拣挪,再用IN查詢單頁(yè)數(shù)據(jù)擦酌。
  2. 對(duì)熱門(mén)數(shù)據(jù)緩存,如前n頁(yè)菠劝。
  3. 在頁(yè)數(shù)很靠后時(shí)赊舶,MySQL的limit會(huì)有比較大的性能問(wèn)題,可以按倒數(shù)第n頁(yè)的思路將排序方式反轉(zhuǎn)查詢赶诊。

另一種分頁(yè)參數(shù)設(shè)計(jì)

在使用數(shù)據(jù)庫(kù)做分頁(yè)查詢時(shí)笼平,常見(jiàn)的方式通過(guò)行號(hào)rownum(SQL Server 、Oracle)或偏移offset(MySQL舔痪、SQL Server)來(lái)實(shí)現(xiàn)寓调,因此有時(shí)候會(huì)將接口的參數(shù)設(shè)計(jì)成rowStart和rowCount。

rowStart锄码,起始行索引夺英,從0開(kāi)始,rowStart = pageIndex * pageSize
rowCount滋捶,單頁(yè)行數(shù)痛悯,即pageSize

但這種行方式設(shè)計(jì)要是需要轉(zhuǎn)為page參數(shù),卻容易出現(xiàn)不兼容重窟,比如rowStart=1载萌,rowCount=5,此時(shí)上述的轉(zhuǎn)換關(guān)系不成立。之前在做接口切換時(shí)遇到過(guò)一次扭仁,為做到兼容垮衷,使用了如下的轉(zhuǎn)換算法,本質(zhì)是找出可以覆蓋到rowStart到rowEnd(rowStart+rowCount)的最小pageIndex和pageSize乖坠,然后從結(jié)果中取出最終需要的subList即可搀突。

/// 分頁(yè)參數(shù)換算
/// </summary>
/// <param name="rowIndexStart">起始行索引,從0開(kāi)始瓤帚,包含</param>
/// <param name="rowCount">單頁(yè)行數(shù)</param>
/// <param name="pageIndex">頁(yè)碼索引描姚,從0開(kāi)始</param>
/// <param name="pageSize">單頁(yè)行數(shù)</param>
/// <param name="resultIndexStart">最終結(jié)果起始索引,從0開(kāi)始戈次,包含</param>
private static void Row2Page(int rowIndexStart, int rowCount, out int pageIndex, out int pageSize, out int resultIndexStart)
{
  if (rowIndexStart < 0 || rowCount <= 0)
  {
    pageIndex = 0;
    pageSize = 10;
    resultIndexStart = 0;
    return;
  }
  pageSize = rowCount;
  while (rowIndexStart % pageSize + rowCount > pageSize)
  {
    pageSize++;
  }
  pageIndex = rowIndexStart / pageSize;
  resultIndexStart = rowIndexStart - pageIndex * pageSize;
}

http://zhiheng.me/156

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末轩勘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子怯邪,更是在濱河造成了極大的恐慌绊寻,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悬秉,死亡現(xiàn)場(chǎng)離奇詭異澄步,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)和泌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)村缸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人武氓,你說(shuō)我怎么就攤上這事梯皿。” “怎么了县恕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵东羹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我忠烛,道長(zhǎng)属提,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任美尸,我火速辦了婚禮冤议,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘师坎。我一直安慰自己恕酸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布屹耐。 她就那樣靜靜地躺著尸疆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惶岭。 梳的紋絲不亂的頭發(fā)上寿弱,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音按灶,去河邊找鬼症革。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鸯旁,可吹牛的內(nèi)容都是我干的噪矛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼铺罢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼艇挨!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起韭赘,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缩滨,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后泉瞻,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體脉漏,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年袖牙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侧巨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鞭达,死狀恐怖司忱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碉怔,我是刑警寧澤烘贴,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站撮胧,受9級(jí)特大地震影響桨踪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芹啥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一锻离、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧墓怀,春花似錦汽纠、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春碴犬,著一層夾襖步出監(jiān)牢的瞬間絮宁,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工服协, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绍昂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓偿荷,卻偏偏與公主長(zhǎng)得像窘游,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子跳纳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • SQL 優(yōu)化(載錄于:http://m.jb51.net/article/5051.htm) 作者: (一)深入淺...
    yuantao123434閱讀 735評(píng)論 0 7
  • asp.net mvc 自定義Pager實(shí)現(xiàn)分頁(yè) Intro 一個(gè)WEB應(yīng)用程序中經(jīng)常會(huì)用到數(shù)據(jù)分頁(yè)忍饰,本文將實(shí)現(xiàn)一...
    天天向上卡索閱讀 1,267評(píng)論 1 6
  • width: 65%;border: 1px solid #ddd;outline: 1300px solid #...
    邵勝奧閱讀 4,833評(píng)論 0 1
  • 從我原來(lái)的房間后窗可以直接看到奶奶的墓,換句話說(shuō)寺庄,奶奶去世后就換了個(gè)地方關(guān)注著我們家喘批。 只是每次都不忍也不敢直視。...
    佘_冬冬閱讀 644評(píng)論 0 4
  • 所謂成熟,還是要懂得尊重他人和尊重自己逛拱。 己所不欲敌厘,勿施于人。不要給自己找難受朽合,也別給他人找難受俱两,此為成熟之道。
    牧云千里外閱讀 118評(píng)論 0 0