在MySQL中,我有一个简单的SELECT查询,可根据特定条件(num_likes,num_comments等)对帖子进行排序。
为了将这些帖子加载到我的应用程序中,我使用LIMIT和OFFSET来显示每页的n个帖子数量。但是,由于插入了新记录,SELECT查询的结果可能会发生变化。因此,以前的结果可能会重新出现在后续页面中。
是否可以防止这种情况发生?
答案 0 :(得分:0)
创建以前查询中出现的ID的二进制搜索树,并将其与当前查询中的ID进行比较。如果有重复的ID,请不要显示这些记录。
它是一种简单的O(logn)算法。
答案 1 :(得分:0)
是的,可以避免/防止这种情况发生。一种方法是避免使用 LIMIT m,n
(或LIMIT n OFFSET m ), and just use **
LIMIT n` **,以及来自"已保存的"值上一页上最后一行。
使用查询中保存的值来获取下一页。
假设此查询返回要显示的行的第一页:
SELECT t.num_likes
, ...
, t.id
ORDER BY t.num_likes DESC, t.id DESC
LIMIT $pagesize
我们为最后一行保留id
和num_likes
的值,以便在下一个查询中使用。对于" next"查询,我们使用这样的值:
SELECT t.num_likes
, ...
, t.id
FROM mytable t
WHERE t.num_likes <= :last_seen_num_likes
AND (t.num_likes < :last_seem_num_likes OR t.id < :last_seen_id)
ORDER BY t.num_likes DESC, t.id DESC
LIMIT $pagesize
例如,如果页面上的最后一行是num_likes=214
和id=42
,那么查询将获得接下来的50行:
SELECT t.num_likes
, ...
, t.id
FROM mytable t
WHERE t.num_likes <= 214
AND (t.num_likes < 214 OR t.id < 42)
ORDER BY t.num_likes DESC, t.id DESC
LIMIT 50
使用此方法基本上保留了行列表中的位置,即使之前添加了行也是如此。我们不是尝试重新计算到同一位置,而是使用保留值来保留我们在列表中的位置。
如果你想启用&#34;之前的&#34;页面功能,也保留了&#34;首次出现的&#34;行,你可以运行类似的查询,只需翻转不等式比较的方向。
(这没有解决num_likes
在查询之间更改行的问题,有效地重新排序列表中的那一行。)
答案 2 :(得分:0)
将最后一项的id显示为SQL的一个参数。然后更改您的代码,以便在按下“下一页”时,它会返回相关项之后的前n个项目。