ORDER BY random()和SQLITE中的种子

Lud*_*uda 20 php sqlite random objective-c ios

我想为随机集实现分页

Select * from Animals ORDER BY random(SEED) LIMIT 100 OFFSET 50  
Run Code Online (Sandbox Code Playgroud)

我试图将int设置为某个整数和某些断裂.不行

如何在sqlite中随机播种?

我在这里抓住机会,因为类似的问题已经存在 - 播种SQLite RANDOM().我只是没有得到PHP解决方案.

mva*_*len 16

简短回答:

你不能.SQLite的random()函数不支持种子值.

答案不是那么简短:

检查SQLite的func.c表明random()是在没有任何参数的情况下定义的.

VFUNCTION(random,            0, 0, 0, randomFunc       ),
Run Code Online (Sandbox Code Playgroud)

..并且此randomFunc()只调用sqlite3_randomness()(再次没有任何显式种子值)来获取sizeof(sqlite_int64)字节的随机值.

在内部,sqlite3_randomness()(参见random.c)的实现将在第一次使用从操作系统获得的随机种子值时设置RC4伪随机数生成器:

  /* Initialize the state of the random number generator once,
  ** the first time this routine is called.  The seed value does
  ** not need to contain a lot of randomness since we are not
  ** trying to do secure encryption or anything like that...
  **
  ** [..]
  */
  if( !wsdPrng.isInit ){
      [..]
      sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
      [..]
      wsdPrng.isInit = 1;
  }
Run Code Online (Sandbox Code Playgroud)

实际上,SQLite的单元测试函数本身只是在全局sqlite3Prng结构上使用memcpy()来保存或恢复测试运行期间PRNG的状态.

所以,除非你愿意做一些奇怪的事情(比如创建一个连续数字的临时表(1..max(动物)),然后将它们洗牌并用它们从你的动物表中选择'随机播种'的RowIds)I假设你运气不好

  • 当然,它们是完全不同的产品.两者都是使用SQL标准的关系数据库系统,但这就是它. (2认同)

use*_*080 6

我通常不会复制现有的答案,但我可以看到你留下了一个评论,要求这个答案的作者在几周前解释它是如何工作的,并且没有给出任何解释.因此,我将复制相关部分,并尝试解释最新情况.如果这个解释很好,请去原始答案投票.

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

前两行只是创建一种种子.结果是带有大量小数的十进制数字,如:

0.54534238371923827955579364758491
Run Code Online (Sandbox Code Playgroud)

然后sql select使用此数字乘以SQLite表中每行的数字行id .然后根据结果产品的小数部分对行进行排序.使用更少的小数,排序顺序看起来像这样:

row id   row id * seed      sort order
1        0.545342384        545342384
2        1.090684767        090684767
3        1.636027151        636027151
4        2.181369535        181369535
5        2.726711919        726711919
6        3.272054302        272054302
7        3.817396686        817396686
8        4.362739070        362739070
Run Code Online (Sandbox Code Playgroud)

排序后,这将是结果:

row id   row id * seed      sort order
2        1.090684767        090684767
4        2.181369535        181369535
6        3.272054302        272054302
8        4.362739070        362739070
1        0.545342384        545342384
3        1.636027151        636027151
5        2.726711919        726711919
7        3.817396686        817396686
Run Code Online (Sandbox Code Playgroud)

在这个示例中,我只使用了八行,因此结果不是很随机.使用更多行时,结果将显得更随机.

只要满足以下条件,此解决方案将重复提供相同的订单:

  • 你使用相同的种子
  • 表中没有出现新行,也没有从表中删除任何行