分页接口设计

两种分页方式

传统的分页方式页最典型的特点是页面上有一连串的页码,和电梯按钮相似,因此页常被称之为电梯式分页。

电梯式特点:

  • 通过页码进行分页
  • 通过点击上/下页按钮可实现页面切换
  • 通过点击页码可实现页面切换
  • 可直接跳转至指定页面
  • 多用于 PC 端,适合需要查找特定内容的页面
  • 需要计算总数or总页数(搜索引擎等场景也可以无需计算,相应的跳转按钮会有所限制)

电梯式分页适用于传统的页面布局,而在移动端页面上更流行的是瀑布流布局方式,相应的分页方式称为流式分页,有时也称为无限下拉式分页。

流式分页特点:

  • 通过滚动/上拉/点击等方式加载新一页
  • 无页码
  • 无上/下页按钮
  • 不可跳转至指定页面
  • pc端和移动端均有使用,适合UGC、视觉内容以及推荐系统等“浏览型”页面
  • 无需计算总数or总页数

对于用电梯式分页方式的接口,有页码、页大小以及结果总数等参数,页码需要明确是从1开始还是0开始,一般使用pageNumber表示从1开始,使用pageIndex表示页索引从0开始,pageSize和limint均可表示单页数据量。totalCount和totalPage可以分别表示总数据条数和总页数。

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

当然,对于流式分页,上述的接口设计也满足要求,但在大多数场景下,可以使用更适合的设计,比如游标式(下文会介绍)。

常见问题

数据缺失:获取后页时,前页数据有删除。此时,本应出现在后页的内容被“顶”到前页,而前页已经加载过了不会重新加载,后页又无此内容,从而无法被用户看到。

数据重复:获取后页时,前页数据有插入。此时,原本在前页的内容被“压”到后页,导致前后也都有此数据,在用户端就是重复数据。

性能问题:较大页码的数据获取时性能会下降,计算总数也会带来额外的开销。

解决方案:

  1. 游标式分页参数设计:
  • 客户端记录当前分页的最后一条数据的 ID(curcor)
  • 请求下一页的时候,从这个 ID 开始获取一页大小(pageSize)的内容

优点:

  • 能够避免数据重复/遗漏
  • 无需计算offset,性能更稳定

缺点:

  • 只适用于按照时间追加的方式等简单排序
  • 无法跳到指定页,适合流式分页
  1. 一次性下发或缓存所有ID
  • 请求第 1 页数据之前/时先缓存所有 ID 列表
  • 请求第 2,3,…n 页数据时,只需传入单页相关的 ID 列表参数

优点:

  • 可将排序由数据库移到应用容器,同时仅取ID一列,降低DB压力。
  • 无需重复计算总数,性能更优更稳定。

缺点:

  • 仅适用于 id 列表不会很大(数百条数据)的业务场景
  1. 限定数据生成时间

分页参数中再额外多一个timestamp参数,第一页请求时timestamp由后端生成并传给前端,前端在后页查询时将此值再次传回给后端,后端在查询条件中只用此值限定数据插入时间。

此方法可以解决数据重复,但无法解决数据缺失,因此适用于只增不删或极少删的场景。

常见性能问题优化方法

  1. SQL查两次,先查出所需页的ID,再用IN查询单页数据。
  2. 对热门数据缓存,如前n页。
  3. 在页数很靠后时,MySQL的limit会有比较大的性能问题,可以按倒数第n页的思路将排序方式反转查询。

另一种分页参数设计

在使用数据库做分页查询时,常见的方式通过行号rownum(SQL Server 、Oracle)或偏移offset(MySQL、SQL Server)来实现,因此有时候会将接口的参数设计成rowStart和rowCount。

rowStart,起始行索引,从0开始,rowStart = pageIndex * pageSize
rowCount,单页行数,即pageSize

但这种行方式设计要是需要转为page参数,却容易出现不兼容,比如rowStart=1,rowCount=5,此时上述的转换关系不成立。之前在做接口切换时遇到过一次,为做到兼容,使用了如下的转换算法,本质是找出可以覆盖到rowStart到rowEnd(rowStart+rowCount)的最小pageIndex和pageSize,然后从结果中取出最终需要的subList即可。

/// 分页参数换算
/// </summary>
/// <param name="rowIndexStart">起始行索引,从0开始,包含</param>
/// <param name="rowCount">单页行数</param>
/// <param name="pageIndex">页码索引,从0开始</param>
/// <param name="pageSize">单页行数</param>
/// <param name="resultIndexStart">最终结果起始索引,从0开始,包含</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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容

  • SQL 优化(载录于:http://m.jb51.net/article/5051.htm) 作者: (一)深入浅...
    yuantao123434阅读 731评论 0 7
  • asp.net mvc 自定义Pager实现分页 Intro 一个WEB应用程序中经常会用到数据分页,本文将实现一...
    天天向上卡索阅读 1,260评论 1 6
  • width: 65%;border: 1px solid #ddd;outline: 1300px solid #...
    邵胜奥阅读 4,806评论 0 1
  • 从我原来的房间后窗可以直接看到奶奶的墓,换句话说,奶奶去世后就换了个地方关注着我们家。 只是每次都不忍也不敢直视。...
    佘_冬冬阅读 641评论 0 4
  • 所谓成熟,还是要懂得尊重他人和尊重自己。 己所不欲,勿施于人。不要给自己找难受,也别给他人找难受,此为成熟之道。
    牧云千里外阅读 116评论 0 0