Функция MySQL RAND()
может принимать целое число в качестве аргумента для использования в качестве начального числа, всегда приводя к одному и тому же результату:
Чтобы продемонстрировать это, вот таблица с тремя одиночными-колонка строковых записей в нем:
mysql> select * from chartest;
+--------+
| string |
+--------+
| AA |
| AB |
| BB |
+--------+
3 rows in set (0.00 sec)
Если я использую 1 в качестве моего начального значения для rand()
в моем 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)
Выбор начального числа
Вы можете преобразовать идентификатор сеанса пользователя в целое число и передать его этой функции так,что для этой сессии результаты всегда будут упорядочены одинаково.
Если, например, идентификатор сеанса является хешем MD5, чтобы избежать необходимости иметь дело с большими (160-битными) целыми числами, которые представляют эти значения, просто удалите символы из строки (используя, например, preg_replace ('/[^\d\s]/', '', $sessionid);
),Затем возьмите первые 5 или около того цифр и преобразуйте их в (int)
для использования в качестве начального числа:
$seed = substr($numeric_id, 0, 5);
Обновление
Для передачи параметра в функцию RAND()
при использованииCakePHP, чтобы убедиться, что он рассматривается как целое число, а не строка, попробуйте использовать следующий синтаксис в order
массива $conditions
:
'order' => 'RAND(CAST('.$seed.' AS SIGNED))'