PHP-分页数据可能重复问题

项目合作 项目合作 主题:1030 回复:2135

PHP-分页数据可能重复问题

晚风撩人 发布于 2016-11-20 字数 837 浏览 1611 回复 13

场景

用户打开一页面,向服务端请求10条最新数据(第1页), 然后用户继续停留在这个页面,5分钟后,用户请求第2页数据。
在这5分钟时间内, 服务器中新增加了数据。

问题

如果服务器中数据是按 权重和ID倒序排序的( SELECT ... order by weight DESC, id DESC LIMIT 0, 10),
传统的分页处理方式,通过将下一页数据时发送第几页( http://host/news?page=2), 那么服务端中使用 select ... limit ... offset 的话, 像上述所描述的场景,拿到的第2页数据会有部分和第一页的相同。

请问,有什么方法解决第2页不拿重复数据的问题?

请求下一页的数据时,不只传页码,再加上上一页请求的最后那行数据的id和weight的值也可能不行。
如果请求下一页的数据, 将上一页及上一页之前的所有id提交到服务器, 如果页数比较多的话,数据就比较大了。 因是App应用,想数据尽可能的少。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

支持 Markdown 语法,需要帮助?

评论(13

泛泛之交 2017-10-15 13 楼

既然是ID排序可以在分页后跟当前页面最后一个ID为参数,但你的SQL让这么做变得复杂
首先生产环境下前端是不需要如此精确的,例如淘宝,amazon都会有一页显示50条数据,但可能只显出48条,第二页重复第一页商品的情况更是常见,这不重要,没必要为此增加逻辑复杂度
新增商品后,第二页显示当前正确的第二页还是专为客户端显示一个该客户端的第二页这是皆有正确性的选择

如果必须这么做,只能将weight与id传入URL参数,然后where weight<xx&&id<0

虐人心 2017-09-08 12 楼

可以这样每次搜索时把第一条数据的id记下,若不重新按搜索键不更新此值,翻每页都带上这个id就可以了,在where条件上限制一下就可以了。

清晨说ぺ晚安 2017-07-20 11 楼

一般情况下这是可以忽略的,当打开第一页后,数据源更新了,再打开第二页,势必会在第二页上产生与第一页重复的几笔数据。如果,必须去控制的话,倒是可以建议你采用断开连接后查询,当进入页面后读出数据并断开连接,只要不是重新进入页面就不会去与数据库同步,在之前,公司给一个政府服务部门做系统时曾用到过,不过效果不好,在二次开发时去掉了。

想挽留 2017-07-14 10 楼

不知道具体的分页内容是什么。
如果类似于新浪微博之类的消息,实时查询数据库的方式是不可取的。可以考虑建立为每个用户建立队列的方式,新数据就是未读数据。为每次请求生成不同条数的内容来处理。
如果是普通数据。
动态修改第一个页面的缓存个数即可。

夜无邪 2017-06-29 9 楼

我觉得这是正常现象,没必要增加逻辑,如果非要保证用户看到的每一页都是不变的,本身就不符合逻辑,数据库的数据一直在变,当然查询出来的也在变。以前对这个问题也有过思考,有种实现方法:你可以一次查出100条数据,吧这个数据放入一个容器,然后放入session或者以其他方式保存。假如你分页每页20条数据,这100条就是5页。用户点击的页码没超过5时,你就直接从这个容器取值。超过了,比如用户点击第20页,你再查询数据库。这样当然是有问题的,不能保证数据的实时性,不过还能满足你的需求,对于实时性要求比较强的网站,像购物的网站,这个是不适合的

偏爱自由 2017-06-12 8 楼

感觉不可避免吧,一般这样的情况是可以忽略的,如果真想不重复的话,我有几个思路:

1,缓存数据,比如取100条数据,按照每页显示数量分割,使用memcache分页,如果又浏览到第一页,重新缓存数据,或者直接来个过期时间。

2,使用nosql数据记录最新的数据,最新数据达到一定数量后同步到数据库,这样可以减少一些重复的情况,完全不重复也做不到。

3,每次访问第一页时,将第一条数据的id记录即:maxId(记录方式可以是session),那么浏览其他页面的slq可以写为:

SELECT ... where id < maxId order by weight DESC, id DESC LIMIT ofset, 10

同样再次浏览到第一页时,重新更新这个值。。

晚风撩人 2017-06-01 7 楼

个人认为要避免重复的问题可以再增加一个字段,以某一时刻或者其他有规律可循的字段进行一个标记,但这样相当于在where后又加了一个条件,对于查询效率肯定有影响,但我只想到这么做,而且实际也没遇到过这种情况,只是我的浅见。
貌似微博的浏览就是不重复的,但不知道后端是如何进行区分的,猜想可能是根据时间。

虐人心 2017-04-18 6 楼

这种情况应该是正常现象吧?除非使用数据库的Rownum排序和分页或许能解决吧,但是你是否考虑到如果等待的时间内删除了,你向前翻页不也会出现重复的么?
而且这样计算的总的翻页数也要保持不变才行啊

清晨说ぺ晚安 2017-03-23 5 楼

我说说 我的想法:
你使用的是数据库自带的分页吧..因为 数据库自增的id和你分页查询的id有相交的地方, 有2种方式:
1.先查询出来 在根据分页码和页面显示条数控制,
2.在新增记录的时候,就先区分是编号是多少的。这个编号和你的自增id不同 就相当于和你唯一标识的是一样的观念。。你排序的是编号。分页也是采取编号,
第2种 我使用过 ,使用在关注度上

浮生未歇 2017-02-27 4 楼

因为看到你说你的是一个APP应用,你的瓶颈在于已经打开的页面数据可能会被新增的数据翻页时被推到后面,其实我觉的如果是APP应用的话,就不要采用常规的分页,比如翻页的时候记录位置是还是按照上一页打开也数据的最后id为翻页的起始id,通过比如用户滑动屏幕到底部时触发下一页的加载,同时的新的数据可以通过下拉屏幕触发最新数据的加载,其实这些已经是很多手机客户端读取数据的策略了,比如微博类,空间说说类的,(如果是网页形式的,触发实现困难的话可以通过论坛类似的新消息提示来提示用户来叠加加载新数据...)其实就是相对翻页,而不是我们普通均等分页,这样的话,类似select ... limit ... offset 这样的语句就需要修改一下查找方式了...就像你后面手的,通过记录id来进行。

晚风撩人 2017-01-28 3 楼

可以使用生成静态页的方式避免类似情况,类似于缓存机制!

浮生未歇 2017-01-02 2 楼

这是个普遍存在的问题,因为思维上的混淆,其实我们看到的第一页应该是最后一页,这是最后发布的内容,但是我们让它倒序显示了,所以就会出现向后挤压,曾经看过一个翻页类是这样写的,显示的页面是从大到小的,这样可以保证每一页都不会出现改变,内容一致性很强,看是由于seo喜欢变化等原因这种方式不被采用。如果你希望在一定时间内页面看到的内容可以保持不变化可以采用缓存,时间长一些

夜无邪 2017-01-01 1 楼

可以采用类似瀑布流的Ajax翻页

前台所有数据ID输出至模板
Ajax传值的时候通过JS遍历当前页面的所有ID传入后台

比如请求 /backend?id=1|2|3
后台生成SQL时将这些ID排除即可

WHERE id != 1 AND id != 2 AND id != 3