播种 SQLite RANDOM()
Posted
技术标签:
【中文标题】播种 SQLite RANDOM()【英文标题】:Seeding 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) 在两个地方都是一样的 它发生了。
如果没有,有没有办法只使用一个查询来存档相同的效果?
【问题讨论】:
【参考方案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 内存数据库表