几种常见的API接口分页方案

1 概述

列表是互联网产品中很常见的一种内容排列形式,而且列表的数据集往往成千上万,一次性返回全量数据集的场景几乎不存在,所以出现了数据分页的需求。本文将总结常见的列表样式以及接口分页设计相关问题。

2 分页方案

常见的列表样式有卡片流、瀑布流、信息流等,我们可以总结为两种分页方式:

  • 传统分页:通过显示的页码查询指定页的数据,多用于 PC 端数据变化不频繁的列表展示。
  • 流式分页:通过滚动方式隐式加载更多的数据,适用 PC 和移动端大多场景。

2.1 基于偏移量

基于偏移是最常见的分页接口设计,其原理是通过页号和页大小指定某一分页的数据。例如:

// 请求
{
    
    
  "page": 2,
  "count": 10
}
// 响应
{
    
    
  "data": [],
  "total": 100
}

具体到数据库可以通过 offset + limit 实现:

select xxx from xxx where xxx order by xxx limit $count offset ($page-1)*$count;

或使用内存分页:

list = list.stream()
    .skip((page-1)*count)
    .limit(count)
    .collect(Collecters.toList());

这种方案比较适合传统显示分页场景,有点是实现起来简单,支持分页跳转,支持向前、后翻页。

缺点也比较明显,主要来自两方面:

  1. 慢查询:通过数据库 limitoffset 实现的分页性能较差,偏移量越大越明显。
  2. 动态数据:偏移量方案对数据变动支持也差,数据的插入或删除可能会导致数据重复或跳过,比如用户在查看第 10 页内容,此时第 1 页一条数据被删除,此时整个列表会往迁移,这会导致第 11 页跳过了 1 条数据。

2.2 基于游标

基于游标(cursor)的分页设计适用于动态数据场景,其原理是根据已获取的最后一条数据的 ID 作为参数来请求下一页数据。例如:

// 请求
{
    
    
  "cursor": "2",
  "count": 10
}
// 响应
{
    
    
  "data": [],
  "nextCursor": "3",
}

实现游标有很多方法,对于有自增主键 ID 的数据库表来说,按 ID 排序分页的实现比较简单,可以直接使用主键 ID 做 cursor:

扫描二维码关注公众号,回复: 14581377 查看本文章
select xxx from xxx where xxx and id>=$cursor limit $count+1;

这里有一个小技巧,可以每次分页查询都多查询一个元素作为 nextCursor 使用,同时可以用来判断是否有剩余数据。

游标分页方案优点就是性能好,对数据变动也有较好支持,不会因为数据的插入或删除导致数据重复或跳过。缺点是不能像偏移量方案可以任意跳转指定页,往前翻页也需要特别处理。

3 重复数据处理

3.1 基于时间

比如我们的微信朋友圈或者微博关注列表,是基于一个维度固定排序的。此类场景中数据只会从最后新增或删除,因此只需要维护好每个用户或 Session 维度的缓存即可。

由其朋友圈关系类数据,由于用户朋友关系数量的限制,完全可以在用户发布动态时以写扩散的方式讲数据分别写入对应朋友的朋友圈数据列表。为了提高该列表的性能,此列表除了使用 MySQL 等数据库持久化外,还可以使用 Redis 的 Zset 数据结构进行高效的缓存。

3.2 基于热度

在基于排序规则定期排序的数据列表场景,如微博热榜中,数据在列表中的位置会不断发生变化,这会导致用户在请求第二页时可能刷到重新排序后的第一页中的数据。

解决该问题很简单,数据的不断变化导致数据分页的复杂,那我们将数据分割成固定不变的数据处理即可使问题简单化:利用场景中定时更新的机制,维护多个版本的数据,用户第一次(或第一页)请求和一个数据版本绑定,这样就保证了数据的不重复。

这里的版本数量可以根据更新时间和用户停留时间估算,还可以采用一致性 Hash 的设计。

当然,如果列表数据集较少,完全还可以获取一次数据客户端进行分页。

3.3 基于推荐

在推荐列表场景中,数据列表并固定的排序规则,并且支持无限拉取,如抖音视频推荐列表。此列数据主要来源推荐系统定向召回和排序后数据,没有明确的分页界限,所以只需要对应的数据量即可,常见方法是在服务端基于用户投递历史以及客户端本地全量缓存进行去重过滤。

由于接口需要实时计算,请求耗时较长,往往会进行预请求,比如在列表倒数第几位开始拉取下一刷的数据。

猜你喜欢

转载自blog.csdn.net/adminpd/article/details/129782021