【问题标题】:Seeding SQLite RANDOM()播种 SQLite RANDOM()
【发布时间】:2011-01-11 09:50:56
【问题描述】:

SQLite 是否像 MySQL 对 RAND() 一样支持播种 RANDOM() 函数?

$query = "SELECT * FROM table ORDER BY RAND(" . date('Ymd') . ") LIMIT 1;";

来自关于RAND(N)的 MySQL 手册:

如果一个常数整数参数 N 是 指定,它被用作种子 值,它产生一个可重复的 列值的序列。在里面 下面的例子,请注意 产生的值序列 RAND(3) 在两个地方都是一样的 它发生了。

如果没有,有没有办法只使用一个查询来存档相同的效果?

【问题讨论】:

    标签: mysql sql sqlite random seeding


    【解决方案1】:

    看看sqlite3_randomness()函数:

    SQLite 包含一个高质量的伪随机数生成器 (PRNG),用于在将新记录插入已使用最大可能 ROWID 的表中时选择随机 ROWID。 PRNG 也用于内置 random() 和 randomblob() SQL 函数。

    ...

    第一次调用此例程(内部或应用程序)时,PRNG 使用从默认 sqlite3_vfs 对象的 xRandomness 方法获得的随机性播种。在所有后续调用中,伪随机性是在内部生成的,无需使用 sqlite3_vfs xRandomness 方法。

    查看这个xRandomness 方法的来源,你可以看到它在Unix 上从/dev/urandom 读取。在 Windows 上,它只返回一些时间函数的返回值。所以看来你唯一的选择就是开始破解 SQLite 源代码。

    【讨论】:

      【解决方案2】:

      如果你需要伪随机顺序,你可以这样做(PHP):

      $seed = md5(mt_rand());
      $prng = ('0.' . str_replace(['0', 'a', 'b', 'c', 'd', 'e', 'f'], ['7', '3', '1', '5', '9', '8', '4'], $seed )) * 1;
      $query = 'SELECT id, name FROM table ORDER BY (substr(id * ' . $prng . ', length(id) + 2))';
      

      另外,您可以将 $seed 设置为预定义的值并始终获得相同的结果。

      我从同事http://steamcooker.blogspot.com/那里学到了这个技巧

      【讨论】:

      • 你能解释一下这个解决方案吗?
      • 不幸的是,这不适用于大型表。
      • Luda,抱歉没有及时回复。 stackoverflow.com/a/24511461/296520 很好地解释了那里发生的事情。
      • 这是否缺少尾括号?我有 ORDER BY (substr(....)
      • @JCx 确实,谢谢!
      猜你喜欢
      • 2014-08-07
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 2011-07-14
      相关资源
      最近更新 更多