Случайное разбиение на страницы результата

У меня в настоящее время есть список данных, которые имеют случайным образом сгенерированный список порядков. Прямо сейчас нет никакого разбиения на страницы, таким образом, для меня легко генерировать случайным образом заказанный список. Когда мой список данных растет, это становится медленнее из-за всех данных, таким образом, очевидным решением является разбиение на страницы. Проблема, которую я имею с разбиением на страницы, - то, что я не могу случайным образом генерировать порядок каждый раз загрузки страницы, таким образом, мой менеджер и я пришли к выводу, что список должен будет быть предварительно сгенерирован заранее и будет повторно создан каждое x количество времени. Теперь проблема - то, как мы храним этот сгенерированный список? Существует четыре опции, которые мы придумали:

  1. Сессия (поднимает поршень на сервере),
  2. Cookie (больше данных передается. Думайте приблизительно тысячи целочисленных значений, переданных пользователю),
  3. Плоский файл (Реализация могла бы занять немного времени. Не экстремальная сумма, но немного дольше, чем остальные)
  4. база данных (задание крона будет выполнять когда-либо x количество времени и делать массовое обновление на всех записях. Наше беспокойство - то, что, если существует слишком много данных, они могли бы замедлить систему, если люди поражают сервер во время обновления.)

Если существуют какие-либо другие решения, которые кажутся лучше, чем предварительно сгенерированные основанные на времени списки, я хотел бы услышать о них.

Спасибо.

ОБНОВЛЕНИЕ: ответ, который я действительно любил, но был удален по некоторым причинам, был то, что кто-то упомянул использование СЕМЕНИ, затем я могу сохранить семя вместо списка идентификаторов, которые были бы сокращение мое хранение данных, и упростите все. Я просто протестировал решение, и оно работает почти безупречно. Единственная проблема состоит в том, что, когда я использую ПРЕДЕЛ, все завинтит. У кого-либо есть предложения к этому? Я не хочу должным быть генерировать все данные каждый раз, когда я просто хочу использовать ПРЕДЕЛ *. Если я использую это с семенем, хотя, числа всегда сбрасывали, как оно должно.

Надо надеяться, тот имевший смысл. Это имело больше смысла, как я думал об этом, чем, как это оказалось введенным.

6
задан JohnathanKong 7 June 2010 в 18:34
поделиться

4 ответа

Mysql RAND() принимает семя в качестве необязательного аргумента. Используя seed, она будет возвращать один и тот же рандомизированный набор результатов каждый раз.

Вы можете сгенерировать случайное зерно в PHP при первом запросе страницы и передавать его каждой странице с помощью строки запроса.

Редактировать: Извините, я не знал, что решение уже было опубликовано, но было удалено.

4
ответ дан 17 December 2019 в 07:00
поделиться

Использовать подзапрос. Таким образом, вы все еще можете использовать трюк RAND () , но OFFSET вас не испортит.

select * from (select * from items order by rand(3) asc) as b limit 5 offset @x;

Альтернативный совет: обновите MySQL. Это была старая ошибка.


Пример:

mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 1;
+-------+
| id    |
+-------+
| 24621 | 
| 25214 | 
| 27119 | 
| 24672 | 
| 25585 | 
+-------+
5 rows in set (0.01 sec)

mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 2;
+-------+
| id    |
+-------+
| 25214 | 
| 27119 | 
| 24672 | 
| 25585 | 
| 27718 | 
+-------+
5 rows in set (0.01 sec)

mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 3;
+-------+
| id    |
+-------+
| 27119 | 
| 24672 | 
| 25585 | 
| 27718 | 
| 25457 | 
+-------+
5 rows in set (0.00 sec)

mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 4;
+-------+
| id    |
+-------+
| 24672 | 
| 25585 | 
| 27718 | 
| 25457 | 
| 27112 | 
+-------+
5 rows in set (0.01 sec)

mysql> select * from (select id from items order by rand(3) asc) as b limit 5 offset 5;
+-------+
| id    |
+-------+
| 25585 | 
| 27718 | 
| 25457 | 
| 27112 | 
| 24779 | 
+-------+
5 rows in set (0.02 sec)
0
ответ дан 17 December 2019 в 07:00
поделиться

Используйте # 4, возможно, сохраняя только идентификаторы извлекаемых данных в том порядке, в котором они должны быть извлечены.

Лучше, если возможно (поскольку это похоже на проблему масштабирования), предварительно сгенерировать данные каждой страницы. Например, если он просматривается только через браузер, просто сгенерируйте заранее x-количество статических страниц HTML (или только часть таблицы / списка).

Я знаю, что это, вероятно, звучит нелепо без дополнительных объяснений, но подумайте об одном из этих вариантов.

Кроме того, если сервер сильно пострадал во время генерации результатов, он должен быть отделен от веб-сервера, и, возможно, отчет / генерация выполняется на клонированном / реплицированном подчиненном устройстве исходной базы данных.

0
ответ дан 17 December 2019 в 07:00
поделиться

Я предпочитаю случайный файл, посмотрите этот класс кеширования, взятый из opencart:

<?php
final class Cache {
  private $expire = 3600; 
  public function __construct() {
    $files = glob(DIR_CACHE . 'cache.*');
    if ($files) {
      foreach ($files as $file) {
        $time = substr(strrchr($file, '.'), 1);
        if ($time < time()) { unlink($file); }
      }
    }
  }

  public function get($key) {
    $files = glob(DIR_CACHE . 'cache.' . $key . '.*');
    if ($files) {
      foreach ($files as $file) {
        $handle = fopen($file, 'r');
        $cache = fread($handle, filesize($file));
        fclose($handle);
        return unserialize($cache);
      }
    }
  }

  public function set($key, $value) {
    $this->delete($key);
    $file = DIR_CACHE . 'cache.' . $key . '.' . (time() + $this->expire);
    $handle = fopen($file, 'w');
    fwrite($handle, serialize($value));
    fclose($handle);
  }

  public function delete($key) {
    $files = glob(DIR_CACHE . 'cache.' . $key . '.*');
    if ($files) {
      foreach ($files as $file) {
        unlink($file);
      }
    }
  }
}
?>

действительно прост в использовании и работает так хорошо, что вы используете случайный запрос и сохраняете свои данные в файл , Выкладываю пример.

$cache = new cache();
$data = $cache->get('my_query_key');
if (!$data) {
  // I do my query and I put it into an array (because I can use shuffle :P)
  $result = mysql_query('SELECT * FROM items');
  $data = array();
  while($row = mysql_fetch_assoc($result)) { $data[] = $row; }
  $cache->set('my_query_key', $data);
}
shuffle($data);

Единственное, с чем возникают проблемы при сохранении файла размером более 100 КБ, но, по слухам, я использую его и работает очень хорошо, никогда не доставляет мне проблем. Ах .. в этом случае не нужно использовать RAND () в запросе. : P

Я написал этот пост без проверки синтаксиса, будьте осторожны ^^

0
ответ дан 17 December 2019 в 07:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: