English 中文(简体)
PHP 随机排序的 MySQL 射程
原标题:PHP MySQL pagination with random ordering
  • 时间:2012-05-24 00:21:31
  •  标签:
  • php
  • mysql

在我的网站上有命令搜索结果 是个问题

当搜索时, 内容页面上出现随机结果, 此页面也包含页码。 用户会跟随我的 SQL 查询 。

SELECT * FROM table ORDER BY RAND() LIMIT 0,10;

所以,我的问题

  1. 我需要确保每次用户访问下一页时,他们已经看到不会再次出现的结果(在下一个查询中排除这些结果,以记忆高效的方式,但仍按兰特()顺序排列)

  2. 每次访客去第一页时 都有不同的结果, 是否有可能使用这个角度, 或者命令总是随机的。

  3. 我可以用MISQL的种子,

最佳回答

在 MySQL 中随机订购是一个同样棘手的问题。 过去, 我通常选择尽可能绕过问题。 通常, 用户不会超过一次或两次回到这样的一连串页面上。 因此, 这给了你一个机会, 来避免所有各种令人厌恶的随机操作, 来支持一对简单的解决方案, 但不是100%的随机解决方案 。

Solution 1

从一些已经为排序而索引的现有列中选择。 这可以包括创建于、 修改的时标或您可能排序的任何其他列。 当用户首次来到网站时, 可以在数组中使用这些工具, 随机选择一个, 然后随机选择 < code> ASC 或 < code> DESC

在您的情况下, 每次用户回到第1页时, 都会选择新的东西, 保存在会话中 。 以后的每页, 您都可以使用这种方式生成一致的传呼 。

Solution 2

您可以增加一个列, 以存储随机数字进行排序。 显然, 它应该被索引化 。 定期运行下面的查询 ;

更新的表格 SET Rand_col = RAND ();

这也许对你的情况不起作用,因为你似乎要求每个用户每次点击第1页时都看到不同的东西。

问题回答

use RAND(SEED) . 引言 docs: "如果指明一个不变整数参数N,则用作种子值。 ( > http://dev.mysql.com/doc/refman/5.0/en/matical-职能.html#conformation_rand

在以上的例子中,结果顺序是兰特,但总是相同的。你可以改变种子,以获得新的顺序。

SELECT * FROM your_table ORDER BY RAND(351);

每次用户点击第一个结果页面并将其存储到用户会话中时,您都可以更改种子 。

首先,您应该停止使用 RAND 语法命令 。 这将对大型行的性能不利 。

您需要手动确定 LIMIT 限制。 如果您仍然想要使用随机结果, 而您不想让用户在下一页看到相同结果, 唯一的办法是将搜索会话的全部结果保存在数据库中, 并在用户浏览到下一页时操作此信息 。

使用网站上的任何随机数据块对用户的视觉感知非常非常糟糕。

  1. random ordering
  2. pagination
  3. HTTP (stateless)

(笑声) (笑声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声(掌声) (掌) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声(掌声) (掌声) (掌声) (掌声(掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声(掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (掌声) (

我的建议取决于你的数据集有多大:

< 强度 > Few 行( a. < 1K):

  • select all PK values in first query (first page)
  • shuffle these in PHP
  • store shuffled list in session
  • for each page call select the data according to the stored PKs

< 加强> 多行 (10K+):

在此假设下, 您有一个名为 AUTO_ INCROINTO < /code > 的独特密钥, 称为 ID , 有可控数的空洞。 如果需要, 请使用 amintenace 脚本( 高删除率)

  • Use a shuffling function that is parameterized with e.g. the session ID to create a function rand_id(continuous_id)
  • If you need e.g. the records 100,000 to 100,009 calculate $a=array(rand_id(100,000), rand_id(100,001), ... rand_id(100,009));
  • $a=implode( , ,$a);
  • $sql="SELECT foo FROM bar WHERE ID IN($a) ORDER BY FIELD(ID,$a)";
  • To take care of the holes in your ID select a few records too many (and throw away the exess), looping on too few records selected.

你们有几个问题要处理!我建议你们一步一步地走下去。

<强势> 第一期: 导致他们已经看到不再出现

  1. Every item returned, store it in one array. (assuming the index id on the example)
  2. When the user goes to the next page, pass to the query the NOT IN:

< 强度 > MySQL 查询

SELECT * FROM table WHERE id NOT IN (1, 14, 25, 645) ORDER BY RAND() LIMIT 0,10;

what this does is to 匹配不是 1, 14, 25 或 645. 的所有 id


就性能问题而言,<强>: 以记忆高效的方式

SELECT RAND( )
FROM table
WHERE id NOT
IN ( 1, 14, 25, 645 )
LIMIT 0 , 10

显示0至9行(共10行,查询用了0.0004秒)

<强 > 和

SELECT *
FROM table
WHERE id NOT
IN ( 1, 14, 25, 645 )
ORDER BY RAND( )
LIMIT 0 , 10

显示0至9行(共10行,查询用了0.0609秒)

所以,不要使用命令 由RAND (), 最好使用 SELECT RAND () 。

我会让您的 PHP 生成您的随机记录号码或行以检索, 将这些号码传送到您的查询, 并在用户客户端上保存一个饼干, 显示他们已经看到的记录 。

该用户特定数据没有理由在服务器上存在(除非您重新跟踪,但无论如何它都是随机的,所以谁在乎)。

So an easier approach would be passing seed value along with the page and limit value. In the API call when you pass the page and limit parameter along with that pass the seed parameter for subsequent API calls.

因此,让我们说我们第一次通过 API 调用中的 < code> page 和 < code> limit 参数。 在后端, 我们随机指定种子值,

// Use the seed value if provided or generate a random seed
    const usedSeed = seed || Math.floor(Math.random() * 100000); // Change the range as needed.

在响应中,我们随此传递种子价值。接下来的呼叫中,我们测试是否在 API 调用中存在种子价值,然后在 SQL 选择查询中传递同样的种子价值, 从而随机地按照相应的顺序对响应和排层进行排列。

const [rows] = await connection.execute(
      `SELECT * FROM generated_results WHERE id IN (${placeholders}) ORDER BY RAND(${usedSeed})`,
      Ids
    );




相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

php return a specific row from query

Is it possible in php to return a specific row of data from a mysql query? None of the fetch statements that I ve found return a 2 dimensional array to access specific rows. I want to be able to ...

Character Encodings in PHP and MySQL

Our website was developed with a meta tag set to... <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> This works fine for M-dashes and special quotes, etc. However, I ...

Pagination Strategies for Complex (slow) Datasets

What are some of the strategies being used for pagination of data sets that involve complex queries? count(*) takes ~1.5 sec so we don t want to hit the DB for every page view. Currently there are ~...

Averaging a total in mySQL

My table looks like person_id | car_id | miles ------------------------------ 1 | 1 | 100 1 | 2 | 200 2 | 3 | 1000 2 | 4 | 500 I need to ...

热门标签