这是我网站上搜索结果排序的问题,当搜索时,随机结果出现在内容页面上,这个页面也包括分页。
SELECT * FROM table ORDER BY RAND() LIMIT 0,10;
字符串所以我的问题是1.我需要确保每次用户访问下一个页面时,他们已经看到的结果不会再次出现(在下一个查询中排除它们,以内存有效的方式,但仍然按兰德()排序)1.每次访问者转到第一页时,都会有不同的结果集,是否可以使用分页,或者排序总是随机的。1.我可以在MySQL中使用种子,但我不知道如何实际使用。
jmo0nnb31#
使用兰德(SEED)。引用文档:“* 如果指定了常量整数参数N,则将其用作种子值。*”(http://dev.mysql.com/doc/refman/5.0/en/prostical-functions.html#function_rand)。
在上面的例子中,结果的顺序是兰德,但它总是相同的。你可以只改变种子来得到一个新的顺序。
SELECT * FROM your_table ORDER BY RAND(351);
字符串您可以在用户每次点击第一个结果页面时更改种子,并将其存储在用户会话中。
bxpogfeg2#
MySQL中的随机排序是一个棘手的问题。在过去,我通常会选择尽可能地绕过这个问题。通常,用户不会超过一次或两次地返回这样的一组页面。因此,这给了你机会来避免所有各种令人厌恶的随机排序实现,而倾向于一些简单的,但不是100%随机的解决方案。
从一些已经被索引的现有列中选择。这可以包括创建时间,修改时间戳或任何其他可以排序的列。当用户第一次访问网站时,将这些列放在数组中,随机选择一个,然后随机选择ASC或DESC。在您的例子中,每当用户返回到第1页时,选择一些新内容,将其存储在会话中。对于随后的每个页面,您可以使用该排序来生成一组一致的分页。
ASC
DESC
你可以有一个额外的列来存储一个用于排序的随机数。显然,它应该被索引。String s =兰德();这可能不适用于您的规格,因为您似乎要求每个用户每次访问第1页时都看到不同的内容。
wbgh16ku3#
首先,你应该停止使用ORDER BY兰德语法。这将对大行集的性能产生不利影响。您需要手动确定LIMIT约束。如果您仍然希望使用随机结果,并且不希望用户在下一页看到相同的结果,则唯一的方法是将此搜索会话的所有结果保存在数据库中,并在用户导航到下一页时操作此信息。在网页设计中,你应该明白的下一件事是-在你的网站上使用任何随机的数据块对用户的视觉感知非常糟糕。
voj3qocg4#
的组合1.随机排序1.分页
几行(约<1K):
这是假设,你有一个名为ID的AUTO_INCREMENT唯一密钥,它有一个可管理的漏洞数量。如果需要,使用amintenace脚本(高删除率)
ID
AUTO_INCREMENT
rand_id(continuous_id)
$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)";
k75qkfdt5#
你有几个问题要处理!我建议你一步一步来。
*第一个问题: 他们已经看到的结果不再出现 *
1.返回的每一项都存储在一个数组中。(假设示例中的索引为id)1.当用户转到下一页时,将NOT IN传递给查询:
id
MySQL查询
SELECT * FROM table WHERE id NOT IN (1, 14, 25, 645) ORDER BY RAND() LIMIT 0,10;
字符串
SELECT RAND( ) FROM table WHERE id NOT IN ( 1, 14, 25, 645 ) LIMIT 0 , 10
型
SELECT * FROM table WHERE id NOT IN ( 1, 14, 25, 645 ) ORDER BY RAND( ) LIMIT 0 , 10
因此,不要使用ORDER BY兰德(),最好使用SELECT兰德()。
3j86kqsm6#
我会让PHP生成要检索的随机记录编号或行,将它们传递给查询,并在用户的客户机上保存一个cookie,指示他们已经看到了哪些记录。没有理由让特定于用户的数据存在于服务器上(除非你正在跟踪它,但它是随机的,所以谁在乎呢)。
f0brbegy7#
因此,一种更简单的方法是将种子值沿着传递页面和限制值。在API调用中,当您传递页面和限制参数时,将种子参数随同传递沿着,以便后续API调用。假设我们第一次在API调用中传递page和limit参数。在后端,我们随机分配一个种子值,
page
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 );
7条答案
按热度按时间jmo0nnb31#
使用兰德(SEED)。引用文档:“* 如果指定了常量整数参数N,则将其用作种子值。*”(http://dev.mysql.com/doc/refman/5.0/en/prostical-functions.html#function_rand)。
在上面的例子中,结果的顺序是兰德,但它总是相同的。你可以只改变种子来得到一个新的顺序。
字符串
您可以在用户每次点击第一个结果页面时更改种子,并将其存储在用户会话中。
bxpogfeg2#
MySQL中的随机排序是一个棘手的问题。在过去,我通常会选择尽可能地绕过这个问题。通常,用户不会超过一次或两次地返回这样的一组页面。因此,这给了你机会来避免所有各种令人厌恶的随机排序实现,而倾向于一些简单的,但不是100%随机的解决方案。
解决方案一
从一些已经被索引的现有列中选择。这可以包括创建时间,修改时间戳或任何其他可以排序的列。当用户第一次访问网站时,将这些列放在数组中,随机选择一个,然后随机选择
ASC
或DESC
。在您的例子中,每当用户返回到第1页时,选择一些新内容,将其存储在会话中。对于随后的每个页面,您可以使用该排序来生成一组一致的分页。
方案二
你可以有一个额外的列来存储一个用于排序的随机数。显然,它应该被索引。
String s =兰德();
这可能不适用于您的规格,因为您似乎要求每个用户每次访问第1页时都看到不同的内容。
wbgh16ku3#
首先,你应该停止使用ORDER BY兰德语法。这将对大行集的性能产生不利影响。
您需要手动确定LIMIT约束。如果您仍然希望使用随机结果,并且不希望用户在下一页看到相同的结果,则唯一的方法是将此搜索会话的所有结果保存在数据库中,并在用户导航到下一页时操作此信息。
在网页设计中,你应该明白的下一件事是-在你的网站上使用任何随机的数据块对用户的视觉感知非常糟糕。
voj3qocg4#
的组合
1.随机排序
1.分页
就像它来的时候一样丑陋:1.和2.一起需要某种“持久的随机性”,而3.使这更难实现。在此之上,1.不是RDBMS优化的工作。
我的建议取决于你的数据集有多大:
几行(约<1K):
多行(10K+):
这是假设,你有一个名为
ID
的AUTO_INCREMENT
唯一密钥,它有一个可管理的漏洞数量。如果需要,使用amintenace脚本(高删除率)rand_id(continuous_id)
$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)";
个k75qkfdt5#
你有几个问题要处理!我建议你一步一步来。
*第一个问题: 他们已经看到的结果不再出现 *
1.返回的每一项都存储在一个数组中。(假设示例中的索引为
id
)1.当用户转到下一页时,将NOT IN传递给查询:
MySQL查询
字符串
id
。**至于性能问题: 以内存有效的方式 *
型
和
型
因此,不要使用ORDER BY兰德(),最好使用SELECT兰德()。
3j86kqsm6#
我会让PHP生成要检索的随机记录编号或行,将它们传递给查询,并在用户的客户机上保存一个cookie,指示他们已经看到了哪些记录。
没有理由让特定于用户的数据存在于服务器上(除非你正在跟踪它,但它是随机的,所以谁在乎呢)。
f0brbegy7#
因此,一种更简单的方法是将种子值沿着传递页面和限制值。在API调用中,当您传递页面和限制参数时,将种子参数随同传递沿着,以便后续API调用。
假设我们第一次在API调用中传递
page
和limit
参数。在后端,我们随机分配一个种子值,字符串
在响应中,我们将种子值沿着传递。因此,对于后续调用,我们测试种子值是否存在于API调用中,然后我们将相同的种子值传递到SQL选择查询中,因此这将随机化响应并按相应的顺序分页。
型