【问题标题】:How to: MySQL order by user_id (RAND) with pagination如何:MySQL 按 user_id (RAND) 和分页排序
【发布时间】:2013-10-16 11:28:48
【问题描述】:

正在寻找一种解决方案,以在单击下一页按钮时在数据库中保持用户表的随机顺序。

实际上我有一个包含 1000 个用户的数据库,我想在每个页面(在成员列表中)显示 10 个用户,我的查询如下所示:

$sql = "SELECT * FROM users ORDER BY user_id LIMIT 1,10";

现在我想 ORDER BY RAND() 并且它可以工作,当然,除了单击下一页时,它会再次随机播放,有时会再次出现相同的用户。

所以我的问题是关于保持我在第一页和下一页上的随机顺序的解决方案。

我想在有人第一次访问成员列表时设置一个 $_SESSION 变量,其中包含 从 1 到 1000 的随机数字,然后按 $_SESSION 变量中的位置对成员进行排序 其中一个数字等于 user_id。

不知道这怎么可能,但我实际上设想了这样的解决方案:

$numbers = range(1, 1000);

$shuffled_numbers = shuffle($numbers);

$sort = $_SESSION['random_user_sort'] = $shuffled_numbers;

所以我在点击第二页(下一页)时会有一个mysql查询,如下所示:

$sql = "SELECT * FROM users ORDER BY $sort LIMIT 11,20";

任何解决方案让它以这种方式工作,甚至更好的想法?

【问题讨论】:

  • 你只有 1000 行,所以只需随机化整个事情并在应用程序级别处理分页 - 所以只有数据库上的命中。
  • 最好不要这样做。你必须知道以前选择的用户——那么如果你有数百万的用户呢? IE。至少会很慢
  • 您能否从用户的角度解释一下您的目标是什么。我的意思是,就业务逻辑而言,您到底想做什么,而不仅仅是您将如何在技术上实现它。我怀疑您想要实现的目标可能有一个更容易扩展的解决方案。
  • 我不希望相同的用户总是出现在首页上。
  • @Strawberry:一次加载所有 1000 行并随机排序它们实际上需要 5 秒才能加载所有内容,所以我正在寻找每个请求最多显示 10 个成员,但保持随机顺序从所有下一页上的所有下一页上的第一页,因此任何成员都不会出现两次或更多。

标签: php mysql session random sql-order-by


【解决方案1】:

RAND() 函数并不真正生成随机数,而是生成所谓的随机数:数字是使用确定性公式计算的,它们只是为了查看随机的。要计算一个新数字,您可以使用前一个数字并将公式应用于它,这就是我们使用确定性函数获得不同输出的方式:通过使用不同的输入

我们使用的初始数字称为seed。如果你have a look at the manual 你会看到RAND() 有一个可选参数:

RAND(), RAND(N)

返回 0 如果 一个常数整数参数 N 被指定,它被用作种子 值,生成可重复的列值序列

你现在可能已经知道我想去哪里了:

mysql> SELECT language_id, name FROM language ORDER BY RAND(33);
+-------------+----------+
| language_id | name     |
+-------------+----------+
|           3 | Japanese |
|           1 | English  |
|           4 | Mandarin |
|           6 | German   |
|           5 | French   |
|           2 | Italian  |
+-------------+----------+
6 rows in set (0.00 sec)

mysql> SELECT language_id, name FROM language ORDER BY RAND(33);
+-------------+----------+
| language_id | name     |
+-------------+----------+
|           3 | Japanese |
|           1 | English  |
|           4 | Mandarin |
|           6 | German   |
|           5 | French   |
|           2 | Italian  |
+-------------+----------+
6 rows in set (0.00 sec)

附:该手册没有明确说明种子范围(它只是说整数),您可能需要一些额外的研究(或只是一些快速测试)。

【讨论】:

  • 完美,这有助于我理解,我现在知道如何保持所有下一页的顺序。谢谢!
猜你喜欢
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 2020-02-15
相关资源
最近更新 更多