播种 SQLite RANDOM()

Posted

技术标签:

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

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

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

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

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

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

【问题讨论】:

【参考方案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,抱歉没有及时回复。 ***.com/a/24511461/296520 很好地解释了那里发生的事情。 这是否缺少尾括号?我有 ORDER BY (substr(....) @JCx 确实,谢谢!

以上是关于播种 SQLite RANDOM()的主要内容,如果未能解决你的问题,请参考以下文章

SQLite Random() 在 ORDER BY 中没有正确排序

未创建 EntityFrameworkCore SQLite 内存数据库表

Codeception sqlite:Laravel 4 中针对 Mockery 的内存

将 sqlite 文件从一个项目复制到另一个项目

将sqlite文件从一个项目复制到另一个项目

SQLite 读取数据时,随机顺序