类似微博抖⾳评论分页的简单设计与实现最近在做⼀个评论分页的实际问题
假设以点赞数排序, 有page_index ,以及 每个评论有个id
我们假设以每⼀页的最后⼀个id在zset中的rank作为left , rank+page_size 为right, 那么
对于实时的分页来说,存在这么⼀个问题
假设前端已经获取了列表1:
comment-1
comment-2
comment-3
comment-4
comment-5
当c5 和 c4 的位置发⽣了变换时,c4 会重复出现⼀次,这是问题1
假设有
page_1:
c1
c2
c3
c4
c5微博关闭评论
page_2:
c6
c7
c8
c9
c10
现在假如c5 和c8交换了位置,那么c6、c7 就丢失掉了。这是问题2
同理如果只以page_index 和 page_index 分页也会有类似的问题
想了⼀个解决⽅案:我们必须引⼊ 点赞数x,且需要对点赞数相同的评论做⼀个id的排序
前端需要传⼀个id + 点赞数x,
我们需要维护的数据结构是: 点赞数第⼀优先级、id作为第⼆优先级(简单的实现⽅式可以是 score=点赞数.id )
获取到x 之后,我们可以先判断这个点赞数的位置,再根据id 去往后筛选page_size 个评论。
但这样存在⼀个问题就是:
如果该评论c5被取消点赞了,导致排名下降了很多,那么他在后⾯⼜会出现⼀次,如果是在page_index + 2以上的页⾯,就⽆法筛掉,这个该怎么解决呢?
或者 c4、c3、c2 被取消点赞,掉了很多排名,也会出现这种情况。
这样的话,看起来有两种处理⽅法: ⼀种是摒弃掉实时刷新的机制、换成5分钟或者⼗分钟刷新⼀次 第⼆种是 由于点赞数会变,所以不将其加⼊到排序规则中
调研⼀下抖⾳的功能可以发现:
前⼏个是热度(点赞数)最⾼的,这⼏个应该是没做分页直接拿的、 后⾯⼏个按时间从新到旧来展⽰(按时间做分页由于时间不会变,所以完全没有重复或丢失的问题)
2019-6-26 续
做的时候发现来⼏个问题
1 ⽤ select * from xxx where id > x limit page_size 可以做sql分页查询,这样没有⾛redis ,所以我在想这个是否⾜够快,⽽且给数据库的压⼒是否⾜够⼩,需要压测和上限看看实际效果
2 如果⾛缓存,那么zset⾥⾯怎么load数据 , 如果load所有评论,则必然有⼀个慢查询,这是我不想要的
如果只load⼀部分,那么做分页写起来挺⿇烦的,需要for循环去到属于那个部分,再查询,不够还需去下⼀个部分查询