0

我有一个数据库,其中有一个 books 表和一个 people 表,每个表大约有 100k 个条目。第三个表将两者连接起来,因此它们具有多对多关系。除了 book 和 person id 的列之外,连接表还有一个列,指示 book 与 person、fx writer、co-writer 或 publisher 或其他东西之间的关系类型。

我需要进行查询,以返回所有书籍条目的列表以及与之相关的人员和特定的关系类型。当连接这两个表时,SQL 会返回多行记录与它相关的多个人的书籍,所以我之后在 php 中对此进行了排序。与书籍相关的人数因书籍而异,没有可预测的模式。

我需要制作一个分页系统。

在这种情况下进行分页的最聪明的方法是什么?

4

4 回答 4

1

你有几种选择,我想说它们可以分为两组

  1. 您发送了所有行并在纯 javascript 中进行分页(在客户端)
  2. 除了您在 sql 查询中指定的限制之外,您还指定了一个偏移量。该偏移量存储在您的 php 会话中,并且每次用户在您的分页中选择下一个/上一个时递增/递减。

优点缺点:

  1. 每个会话一个单一的 sql 查询,没有额外的 http 请求,因为所有都在客户端内部处理。当查看结果时服务器端发生变化时,可视化的结果可能会过时。传输的行数更大,因此第一个可视化的加载时间更长。

  2. 仅查询和处理单个视图实际需要的那些行。更多行仅应请求检索。行总是最新的,但是如果您使用偏移值而同时行数发生变化(极少数情况),事情可能会变得很糟糕。每个下一个/上一个操作一个 http 请求,但单个视图的加载时间更快。


对于由于join导致单书多次点击的问题:

我认为您应该在这里遵循不同的策略:

  1. 或者您使用子查询(查询中的查询),这样您就可以为内部查询指定偏移量和限制,仅在不考虑人员的情况下检索书籍。然后外部查询将人员连接到内部查询的结果。

  2. 不要为与书关联的多个人检索单独的行,而是将这些命中分组并可能通过连接他们的名字或其他东西来加入这些人。就像您检索的每本书中的一组人一样。这样你就可以毫无问题地指定偏移量和限制。

于 2012-11-25T22:14:50.330 回答
1

你需要选择你的书而不离开人们,这样你就可以使用 LIMIT 0,20 用于第 1 页,LIMIT 20,20 用于第 2 页等进行分页

然后分别获取每本书的人员列表。您可以对每本书使用一个 SQL 调用,或者将它们全部用于所选书籍并摆弄该列表,以更快者为准。

于 2012-11-25T22:39:13.680 回答
1

您可以在一行中选择每本书的所有相关人员group_concat,然后使用limit offset, num_rows

select b.book_id, b.title, ..., group_concat(c.type), group_concat(p.name)
from books b
join connections c on c.book_id = b.book_id
join persons p on p.person_id = c.person_id
group by book_id
limit 100, 50
于 2012-11-25T22:41:40.567 回答
0

这是一种糟糕的形式,因为您很可能应该按照前面的答案所建议的那样做——在 SQL 中工作。但是,您发表评论说您在 PHP 中全力以赴。也就是说,如果您在脚本中有所有结果(即不是一个巨大的数据库结果),那么可以很容易地在 PHP 中处理它。

  1. 将结果存储在 $_SESSION 变量中。
  2. 计算结果的长度。
  3. 将结果除以每页的项目数。
  4. for 循环显示第一页项目的结果。
  5. 建立一个链接,将页码与查询字符串或其他方式一起传递..
  6. for 循环从下一页的下一项开始的结果等。

您可能对PHP.net 手册页上提供的 count() 的一些自定义函数感兴趣。

于 2012-11-25T23:12:23.257 回答