【问题标题】:Pagination of MySQL results in PHPPHP 中 MySQL 结果的分页
【发布时间】:2011-06-30 16:15:23
【问题描述】:

直到最近,我才真正将这个(分页)视为一个问题。当我坐下来专注于它时,我发现自己面临着很多问题。

我喜欢的是一个基本的联系人管理系统,用户可以在其中添加/更新/删除/搜索联系人。搜索部分是我需要有效实现分页的地方。

我的想法(带有 +ve 和 -ve 点)

  • 我可以指定pageNooffsetPOSTing 到我的search.php 页面。此页面将触发一个简单的 MySQL 查询来检索结果。由于行数几乎可以达到数千,因此我需要对其进行分页。很简单,但我需要为每个不同的页面一次又一次地触发 same 查询。这意味着,当用户从 page1 转到 page2 时,将触发相同的 MySQL 查询(当然使用不同的offset),我觉得这是多余的,并且正在努力避免。
  • 然后我想捕获整个结果集,并将其存储到$_SESSION,但在这种情况下,如果结果只是巨大怎么办?它会以任何方式影响性能吗?
  • 在与第二点类似的行中,我想将结果写到一个文件中,这简直是废话! (我只是把它放在这里,作为一个观点。我知道这是真正糟糕的做事方式。)

我的问题:

一个。我实施上述哪种方法?哪一个更好?还有其他方法吗?我用谷歌搜索了它,但我发现大多数示例都遵循上面的第 1 点。

B。我对第 1 点的问题:我们如何依赖 mysql 结果的顺序?假设用户在一段时间后导航到 page2,我们如何确定在第二次期间,第一页的记录没有重复? (因为,我们正在做一个新的查询)..

C。 MySQL 资源到底是什么?我知道mysql_query(..) 返回resource。从某种意义上说,它是否是全局的,它维护对 PHP 脚本的不同调用之间的状态? (我可以在$_SESSION 中维护资源)。

谢谢一百万! :-)

PS:我知道这是一个很长的问题。我只是试图以简洁的方式表达我脑海中发生的事情。

【问题讨论】:

    标签: php mysql pagination


    【解决方案1】:

    使用您的第一个建议。带有偏移量的那个。这是进行分页的“标准”方式。将整个结果集放入会话中不是一个好主意,因为每个用户都拥有自己的私有数据副本。如果您遇到性能问题,您可以随时添加缓存 (memcache),这将有利于所有访问数据的用户。

    MySQL 将始终以相同的方式生成您的数据。第 1 页中的记录出现在第 2 页上的唯一方法是在用户从第 1 页导航到第 2 页之间插入新记录。换句话说:您无需担心。

    资源是 MySQL 的情况,是指向结果集的排序指针。然后您可以对其进行操作(逐行获取数据,计算返回的行数等)。它不是全球性的。

    【讨论】:

    • 感谢您的回答!在第二段中,您恰到好处。那只是我心中的确切问题。关于 MySQL 资源,是的,我确实理解它是一个标识某些内部资源的普通指针。但是resource 类型的大小(以字节为单位)是多少?另外,只要 MySQL 服务运行,它是否会被维护(以便我可以在下一次调用我的 PHP 脚本时填充更多结果)?
    • Resource 就像 PHP 脚本中的任何其他变量一样。当脚本完成时,它不再存在。据我所知,资源的大小取决于返回的数据的大小。
    • 只是为了增加这个答案的价值 - 在这里查看可能的分页优化技术:mysqlperformanceblog.com/2006/09/01/…
    【解决方案2】:

    A.当然是第一个。还有其他方法,比如地球上的每一件事,但就像地球上的每一件事一样,首先必须使用最常用和通用的方法,只是因为他们必须熟悉它并且因为它肯定适合您,因为它适合其他网站管理员。
    另请注意,您提出的其他方法不在明智之列。

    B.是的,记录确实跨页移动。没什么不好的。

    C. PHP 中没有任何东西在调用之间维护它的状态。不能在会话中保存任何资源。去偏移分页。

    【讨论】:

    • @Shrapnel:你通常回答的方式,我只是大声笑! :-) 顺便说一句,你能解释一下你的最后一点吗?我真的不明白你的意思。谢谢! :-)
    【解决方案3】:

    在构建 SQL 时,您可以执行以下操作(0 是偏移量,10 是要返回的行数)

    SELECT * FROM `your_table` LIMIT 0, 10 
    

    这将显示数据库中的前 10 个结果。

    替代语法,3 个查询,显示前 30 个结果 1-10,11-20,21-30。

    SELECT * FROM `your_table` LIMIT 10 OFFSET 0
    SELECT * FROM `your_table` LIMIT 10 OFFSET 10
    SELECT * FROM `your_table` LIMIT 10 OFFSET 20
    

    编辑:

    好的,澄清一下,选项 1 是您最好的选择。传入页码。每个查询的限制都是一样的,$offset = ($pageNum - 1 ) * 10;

    您将需要一个ORDER BY 子句。但是,如果数据库的内容在页面加载之间发生变化,用户可能会注意到差异。这实际上取决于您的数据更改的频率。

    我没有尝试在会话中存储 mysql_query() 的结果。我怀疑不是您想使用它的方式。当脚本结束时,您可以考虑隐式调用 mysql_close() 并销毁资源。

    【讨论】:

    • 谢谢,但确切地说,我真正的问题有点不同。 :-)
    • 我已经扩展了它。希望对您有所帮助。
    • 您可以将公式更改为:$offset = ($pageNum - 1) * $results,其中$resultsNo 表示每页的结果计数。在 SQL 中:SELECT * FROM {$your_table} LIMIT {$resultNo} OFFSET {$offset}
    【解决方案4】:

    根据我的经验(不多),我通常使用第一种方法,因为每次您转到另一个页面时,您总是会从 mysql 获取更新的数据。是的,如果您使用按 last_updated_time 排序,那么结果将跨页面移动。

    但我认为这不是你的想法。正如您在第三个问题中提到的那样,也许您希望为结果提供某种缓冲区,但这意味着您必须为每个结果创建缓冲区(这就是您提到使用文件存储 mysql 结果的原因)。

    这可能是您正在寻找的答案(如果这可以被认为是一个答案:LOL),但我的目的只是试图给出一些观点。

    【讨论】:

      猜你喜欢
      • 2012-05-19
      • 2012-09-05
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      相关资源
      最近更新 更多