基于会话的随机查询结果

时间:2011-04-19 12:55:53

标签: mysql cakephp cakephp-1.3

我有一个配置文件表,我想按随机顺序列出配置文件,我已完成如下:

$this->paginate = array('User' => array('conditions'=>array('User.userstanding_id'=>'1'), 'order' => 'RAND()', 'limit' => '10')); 

唯一缺少的功能是,我希望这些配置文件按顺序进行,以便在下一页上没有重复项,甚至一些配置文件在完成所有操作时根本无法查看页面。

我正在寻找的是一种方法,为查询找到一个随机起点,然后从该起点开始按顺序分页。也许每个会话?

2 个答案:

答案 0 :(得分:2)

MySQL RAND() function可以将整数作为参数用作种子,始终产生相同的结果:

为了证明这一点,这里有一个包含3个单列字符串记录的表:

mysql> select * from chartest;
+--------+
| string |
+--------+
| AA     |
| AB     |
| BB     |
+--------+
3 rows in set (0.00 sec)

如果我在rand()中使用1作为ORDER BY的种子值,它将始终产生相同的结果排序:

mysql> select * from chartest order by rand(1);
+--------+
| string |
+--------+
| BB     |
| AA     |
| AB     |
+--------+
3 rows in set (0.00 sec)

mysql> select * from chartest order by rand(1);
+--------+
| string |
+--------+
| BB     |
| AA     |
| AB     |
+--------+
3 rows in set (0.00 sec)

如果我将种子更改为2,则排序会更改:

mysql> select * from chartest order by rand(2);
+--------+
| string |
+--------+
| AB     |
| BB     |
| AA     |
+--------+
3 rows in set (0.00 sec)

选择种子

您可以将用户的会话ID转换为整数并将其传递给此函数,以便对于该会话,结果将始终以相同的方式排序。

例如,如果会话ID是MD5哈希,为了避免必须处理这些值所代表的大(160位)整数,只需从字符串中删除字符(例如使用preg_replace ('/[^\d\s]/', '', $sessionid);)。然后取前5个左右的数字并将其转换为(int)以用作种子:

$seed = substr($numeric_id, 0, 5);

更新

要在使用CakePHP时将参数传递给RAND()函数,要确保将其视为整数而不是字符串,请尝试在$conditions数组的order中使用以下语法:

'order' => 'RAND(CAST('.$seed.' AS SIGNED))' 

答案 1 :(得分:1)

我不是CakePHP的专家,但我想如果你在会话基础上播种RAND函数,那么paginate函数将使用会话种子值在页面之间工作。

e.g

在创建会话时分配种子,只需使用随机数生成器即可。

 $this->paginate = array('User' => array('conditions'=>array('User.userstanding_id'=>'1'), 'order' => 'RAND('.$_SESSION['rndSeed'].')', 'limit' => '10'));