Выборка случайных записей БД без order by rand()...
Поневоле возвращаясь к теме этой заметки, приведу ещё одно возможное решение проблемы.
Вот функция получения нужного количества случайных записей по id
и пример её вызова:
function get_random_rows( $n, $table, $key = 'id' ) { /* $n Количество случайных записей $table Имя таблицы $key Первичный ключ */ $data2 = array(); $sql1 = 'select ' . $key . ' from ' . $table; $result1 = dbquery($sql1); $data1 = array(); if ($result1 and dbrows($result1)) { while ($row1 = dbfetcha($result1)) $data1[] = $row1; } if ($data1) { $count1 = count($data1); $n = ($n <= $count1 ? $n : $count1); $randomindexes = array_rand( $data1, $n ); $randomindexesarray = array(); for ($i=0; $i<$n; ++$i) $randomindexesarray[] = $data1[$randomindexes[$i]][$key]; $sql2 = 'select * from ' . $table . ' where ' . $key . ' in ('. implode(', ', $randomindexesarray) .')'; $result2 = dbquery($sql2); if ($result2 and dbrows($result2)) { while ($row2 = dbfetcha($result2)) $data2[] = $row2; } } return $data2; } $random = get_random_rows (10, DB_TABL, 'id'); for ($i=0; $i<count($random); $i++) { echo '<br>key='.$random[$i]['id'].', value='.$random[$i]['name']; }
"Нестандартные" функции работы с MySQL (по сути дела, сокращения для длинных стандартных имён) "лежат" в файле db.php
приложенного архива.
Правда, здесь 2 запроса, но 1-й получает только идентификаторы записей, что не должно создавать описанных в статье проблем, а второй уже просто берёт фиксированный набор ключей, имея вид вроде
select * from test where id in (3, 11, 17, 19, 37, 47, 53, 59, 61, 71)
Тестовая таблица специально была "с дырками в ключе":
CREATE TABLE test ( id int PRIMARY KEY auto_increment, name varchar(32) ); insert into test values (2,'record1'), (3,'record2'), (5,'record3'), (7,'record4'), (11,'record5'), (13,'record6'), (17,'record7'), (19,'record8'), (23,'record9'), (29,'record10'), (31,'record11'), (37,'record12'), (41,'record13'), (43,'record14'), (47,'record15'), (53,'record16'), (59,'record17'), (61,'record18'), (67,'record19'), (71,'record20');
Вот только проверить подход на действительно большой базе возможности пока не было :)
Скачать архив с примером можно с основной страницы статьи
12.12.2012, 23:43 [10626 просмотров]