redis可以实现分页嘛?可以,怎么实现呢?我们以一篇文章最新评论列表的场景来说。
最新的评论列表中需要包含的是有序的评论内容,我们按照评论时间排序,那评论列表中评论的顺序也是需要按照评论时间来排序的。那Redis
中有那种接口可以实现排序呢?[String,List,Set,Hash,Sorted Set]中,List
和Sorted Set
作为有序集合是可以满足的。List
可以按照元素的插入顺序进行排序,而Sorted Set
可以按照元素的权重来排序,元素的权重可以由我们自己定义。
List实现
每个商品对应一个 List,这个 List 包含了对这个商品的所有评论,而且会按照评论时间保存这些评论,每来一个新评论,就用 LPUSH 命令把它插入 List 的队头。
在只有一页评论的时候,我们可以很清晰地看到最新的评论,但是,在实际应用中,网站一般会分页显示最新的评论列表,一旦涉及到分页操作,List 就可能会出现问题了。
假设当前的评论 List 是{A, B, C, D, E, F}(其中,A 是最新的评论,以此类推,F 是最早的评论),在展示第一页的 3 个评论时,我们可以用下面的命令,得到最新的三条评论 A、B、C:
LRANGE product1 0 2
1) "A"
2) "B"
3) "C"
然后,再用下面的命令获取第二页的 3 个评论,也就是 D、E、F。
但是,如果在展示第二页前,又产生了一个新评论 G,评论 G 就会被 LPUSH 命令插入到评论 List 的队头,评论 List 就变成了{G, A, B, C, D, E, F}。此时,再用刚才的命令获取第二页评论时,就会发现,评论 C 又被展示出来了,也就是 C、D、E。
LRANGE product1 3 5
1) "C"
2) "D"
3) "E"
之所以会这样,关键原因就在于,List 是通过元素在 List 中的位置来排序的,当有一个新元素插入时,原先的元素在 List 中的位置都后移了一位,比如说原来在第 1 位的元素现在排在了第 2 位。所以,对比新元素插入前后,List 相同位置上的元素就会发生变化,用 LRANGE 读取时,就会读到旧元素。
Sorted Set实现
Sorted Set 不会有上述的问题,它是根据元素的实际权重来排序和获取数据的
我们可以按评论时间的先后给每条评论设置一个权重值,然后再把评论保存到 Sorted Set 中。Sorted Set 的 ZRANGEBYSCORE 命令就可以按权重排序后返回元素。这样的话,即使集合中的元素频繁更新,Sorted Set 也能通过 ZRANGEBYSCORE 命令准确地获取到按序排列的数据。
假设越新的评论权重越大,目前最新评论的权重是 N,我们执行下面的命令时,就可以获得最新的 10 条评论:
ZRANGEBYSCORE comments N-9 N
所以,在面对需要展示最新列表、排行榜等场景时,如果数据更新频繁或者需要分页显示,建议你优先考虑使用 Sorted Set。