Заполнение SQLite RANDOM () - PullRequest
       33

Заполнение SQLite RANDOM ()

7 голосов
/ 31 января 2010

Поддерживает ли SQLite заполнение функции RANDOM() таким же образом, как MySQL с RAND()?

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

Из руководства MySQL о RAND(N):

Если постоянный целочисленный аргумент N равен указано, это используется в качестве семени значение, которое производит повторяемое последовательность значений столбцов. в В следующем примере обратите внимание, что последовательности значений, произведенных RAND (3) одинаков в обоих местах, где это происходит.

Если нет, есть ли способ архивировать тот же эффект, используя только один запрос?

Ответы [ 2 ]

10 голосов
/ 31 января 2010

Посмотрите на функцию sqlite3_randomness():

SQLite содержит высококачественный генератор псевдослучайных чисел (PRNG), используемый для выбора случайных ROWID при вставке новых записей в таблицу, которая уже использует максимально возможный ROWID. PRNG также используется для встроенных функций SQL random () и randomblob ().

...

В первый раз, когда эта подпрограмма вызывается (либо изнутри, либо из приложения), PRNG засевается с использованием случайности, полученной из метода xRandomness объекта sqlite3_vfs по умолчанию . При всех последующих вызовах псевдослучайность генерируется внутренне и без обращения к методу sqlite3_vfs xRandomness.

Глядя на источник этого xRandomness метода, вы можете видеть, что он читает из /dev/urandom в Unix. В Windows он просто возвращает возвращаемые значения некоторых временных функций. Таким образом, похоже, что вы можете только взломать исходный код SQLite.

5 голосов
/ 18 марта 2010

Если вам нужен псевдослучайный порядок, вы можете сделать что-то вроде этого (PHP):

$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)';

Кроме того, вы можете установить $ seed на предопределенное значение и всегда получать одинаковые результаты.

Я научился этому трюку от моего коллеги http://steamcooker.blogspot.com/

...