MySQL RAND()可以多久使用一次?它使用/ dev / random吗?

时间:2013-04-02 14:15:38

标签: php mysql random

我有一张几排的桌子(上面50张),我需要从桌子上得到随机值我可以做到这一点 ORDER BY RAND() LIMIT 1
主要问题是,当我在5秒钟内获得6k选择时,rand stil'可靠'? 如何计算兰特,我可以随着时间推移播种吗? (idk,每5秒钟)。

3 个答案:

答案 0 :(得分:5)

MySQL伪随机数生成器是完全确定的。文档说:

  

RAND()并不是一个完美的随机发生器。这是一种快速生成随机数的方法,可以在同一MySQL版本的平台之间移植。

它不能使用/ dev / random,因为MySQL设计用于各种操作系统,其中一些操作系统没有/ dev / random。

MySQL使用time(0)返回的整数在服务器启动时初始化默认种子。 如果您对源代码行感兴趣,那么它位于文件sql / mysqld.cc中的MySQL源代码中,函数init_server_components()。我认为它不会重新播种。

然后随后的“随机”数字仅基于种子。请参阅源文件mysys_ssl / my_rnd.cc,函数my_rnd()


随机选择任务的最佳实践解决方案,无论是性能还是随机质量,都是在最小主键值和最大主键值之间生成一个随机值。然后使用该随机值选择表中的主键:

SELECT ... FROM MyTable WHERE id > $random LIMIT 1

你使用>的原因而不是=是由于行被删除或回滚而导致id中可能存在间隙,或者您的WHERE子句中可能有其他条件,以便在符合条件的行之间存在间隙。

这种大于方法的缺点:

  • 这种差距之后的行有更高的被选择机会,差距越大,机会越大。
  • 在生成随机值之前,您需要知道MIN(id)和MAX(id)。
  • 如果您需要多个随机行,则无法正常工作。

此方法的优点:

  • 它比ORDER BY RAND()快得多,即使是适度的表格大小。
  • 您可以使用SQL之外的随机函数。

答案 1 :(得分:1)

兰德是伪随机的。小心使用它来保护安全。我不认为你的"从五十岁中随机选择一行。是为了安全,所以你可能还可以。

小桌子的速度非常快。从一个大表中挑选一个随机行是很可怕的:它必须用伪随机数标记每一行,然后对它们进行排序。对于你所描述的应用,@ TheEwook的建议是完全正确的;即使是一个小表也可以比一次毫秒一次排序甚至可以淹没强大的MySQL硬件。

除非你正在测试并且你想要一些可重复的随机数序列用于某种单元测试,否则不要种兰德。在生成我认为难以猜测的会话令牌的时候,我学到了很多。 MySQL人员在兰德方面做得很好,你可以相信他们所说的应用程序。

我认为(不确定),如果你不播种它,它会从/ dev / random的随机种子开始。

如果您需要加密等级的随机数,请自行阅读/ dev / random。但请记住,/ dev / random只能产生有限的速率。 / dev / urandom使用/ dev / random来生成更快的速率,但在其熵池中不是高等级。

答案 2 :(得分:0)

如果你的牌桌不是太大(让我们说最多1000张唱片),这并不重要。但对于大牌桌,你必须选择另一种方式。

本文可能对您有所帮助:

http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/