高效的评论系统分页查询

时间:2018-02-02 00:10:32

标签: php mysql sql mysqli pagination

因此,我一直在网上浏览有关分页的任何信息。 从我所看到的有3种,(LIMIT,OFFSET)a,(WHERE id > :num ORDER BY id LIMIT 10)b和(光标分页)c就像在facebook和twitter上使用的那样。

我决定,对于我的项目,我会选择" b"选项,因为它看起来非常简单和有效。

我试图创造某种" facebook"比如帖子和评论系统,但不是那么复杂。

我有一个帖子和评论的排名系统,以及用帖子提取的每篇帖子的前2条评论。

当人们点击查看更多评论时,每个特定帖子的其余评论都会被提取。

这是对帖子评论的查询:

SELECT 
  c.commentID,
  c.externalPostID, 
  c.numOfLikes, 
  c.createdAt, 
  c.customerID, 
  c.numOfComments,
  (CASE WHEN cl.customerID IS NULL THEN false ELSE true END) isLiked,
  cc.text,
  cu.reputation,
  cu.firstName,
  cu.lastName,
  c.ranking
  FROM 
    (SELECT * 
     FROM Comments 
     WHERE Comments.externalPostID = :externalPostID) c
    LEFT JOIN CommentLikes cl ON cl.commentID = c.commentID AND cl.customerID = :customerID
    INNER JOIN CommentContent cc ON cc.commentTextID = c.commentID
    INNER JOIN Customers cu ON cu.customerID = c.customerID 
  ORDER BY c.weight DESC, c.createdAt ASC LIMIT 10 OFFSET 2

offset 2是因为之前有2条评论被提取为前2条评论。

我正在寻找一种方法similar to this每次通过数据库寻找下一个10条评论而不经过所有行,例如LIMIT,OFFSET

问题是我有两列对结果进行排序,我不允许我使用这种方法:

SELECT * FROM Comments WHERE id > :lastId LIMIT :limit;

非常感谢帮助者!

解决方案到目前为止

为了拥有高效分页,我们需要使用单列尽可能多的唯一值来生成序列以帮助我们对数据进行排序通过分页。

我的示例使用两列对数据进行排序,因此会出现问题。 我所做的是结合时间( asc排序顺序)和评论的权重( desc排序顺序),权重总计是多少该评论正在被用户使用。

我通过从DateTime格式中获取纯int数并将数字除以权重来实现它,让我们调用结果,"排名" 。 这样,权重评论的排名总是低于没有评分的评论。

剥离后的DateTime是一个14位数的int,因此它不应该将问题除以另一个数字。

所以现在我们有一个专栏对评论进行排序,其中评论与参与将位于顶部,然后是较早的评论,直到最后发布的评论为止。

现在我们可以使用这种可以很好地扩展的高性能分页方法:

SELECT * FROM Comments WHERE ranking > :lastRanking ORDER BY ASC LIMIT :limit;

1 个答案:

答案 0 :(得分:0)

好的,我想说其他方式,在我看来这非常有用。

$rowCount = 10; //this is count of row that is fetched every time
$page = 1; //this is for calculating offset .  you must increase only this value every time    
$offset = ($page - 1) * $rowCount; //offset

SELECT 
  c.commentID,
  c.externalPostID, 
  c.numOfLikes, 
  c.createdAt, 
  c.customerID, 
  c.numOfComments,
  (CASE WHEN cl.customerID IS NULL THEN false ELSE true END) isLiked,
  cc.text,
  cu.reputation,
  cu.firstName,
  cu.lastName,
  c.ranking
  FROM 
    (SELECT * 
     FROM Comments 
     WHERE Comments.externalPostID = :externalPostID) c
    LEFT JOIN CommentLikes cl ON cl.commentID = c.commentID AND cl.customerID = :customerID
    INNER JOIN CommentContent cc ON cc.commentTextID = c.commentID
    INNER JOIN Customers cu ON cu.customerID = c.customerID 
  ORDER BY c.ranking DESC, c.createdAt ASC LIMIT $rowCount OFFSET $offset

可能有错误,因为我没有检查,请不要重要