Подтвердить что ты не робот

Согласованное случайное упорядочение в запросе MySQL

У меня есть база данных изображений, и я хочу, чтобы посетители просматривали фотографии. У меня есть одна "следующая" и одна "предыдущая" ссылка.

Но то, что я хочу, - это показать каждому посетителю новый порядок фотографий. Как я могу это сделать? Если я буду использовать ORDER BY RANDOM(), я буду показывать иногда повторяющиеся изображения.

Может кто-нибудь мне помочь? Спасибо!

4b9b3361

Ответ 1

Вы можете попробовать использовать семя в случайной функции:

SELECT something FROM somewhere ORDER BY rand(123)

123 - это семя. Случайные должны возвращать те же значения.

Ответ 2

Проблема возникает из-за того, что каждая страница снова запустит RAND() и не сможет узнать, были ли возвращенные изображения ранее возвращены. Вы должны составить свой запрос таким образом, чтобы вы могли отфильтровывать изображения, уже представленные на предыдущих страницах, так что RAND() будет иметь меньше вариантов для выбора.

Идея заключалась бы в рандомизации изображений, выборе идентификаторов, хранении идентификаторов в сеансе, а затем SELECT с использованием этих идентификаторов. Таким образом, каждый пользователь будет иметь рандомизированные снимки, но они смогут прокручивать их без повторной рандомизации их на каждой странице.

Итак, что-то вроде:

  • SELECT id FROM pictures ORDER BY RAND() LIMIT x, если у вас уже нет идентификаторов в сеансе
  • Сохраните идентификаторы в сеансе
  • SELECT ... FROM pictures WHERE id IN (IDs from session) LIMIT x

Другая идея - хранить в сеансе идентификаторы, которые пользователь уже видел, и отфильтровывать их. Например:

  • SELECT ... FROM pictures ORDER BY RAND() LIMIT x, если сеанс не содержит идентификатора
  • Добавить идентификаторы из текущего запроса в сеанс
  • SELECT ... FROM pictures WHERE id NOT IN (IDs from session) ORDER BY RAND() LIMIT x

Другим способом является использование семени, как указывает izi. Я должен сказать, что я не знал о семени, но, похоже, он возвращает те же самые результаты для того же самого значения семени. Итак, запустите свой обычный запрос и используйте RAND(seed) вместо RAND(), где "seed" - это уникальная строка или номер. Вы можете использовать идентификатор сеанса как семя, потому что он гарантированно уникален для каждого посетителя.

Ответ 3

Вы можете засеять случайную функцию, как предложено izi, или отслеживать посещаемые изображения и изображения, которые не были посещены, как было предложено rdineiu.

Я хотел бы подчеркнуть, что ни один из вариантов не будет работать хорошо. Либо вы проведете сортировку всей таблицы (или ее части) с использованием произвольных критериев и извлечете верхние строки n, возможно со смещением. Это будет ужасно медленным.

Итак, подумайте, насколько важно, чтобы каждый посетитель получал другой порядок изображения. Наверное, это будет не так важно, если все будет выглядеть случайным. Предполагая, что это так, рассмотрим эту альтернативу...

Добавьте в таблицу дополнительное поле float, назовите его sort_ord. Добавьте на него индекс. На каждой вставке или обновлении присвойте ему случайное значение. Дело здесь состоит в том, чтобы в конечном итоге иметь, казалось бы, случайный порядок (с точки зрения посетителей) без ущерба для производительности.

Такая настройка позволит вам захватить верхние строки n и разбивать страницы на ваши страницы с помощью индекса, а не сортировать всю таблицу.

По своему усмотрению задание cron периодически устанавливает новое значение:

update yourtable
set sort_ord = rand();

Также по своему выбору создайте несколько таких полей и назначьте их посетителям, когда они посещают ваш сайт (cookie или сеанс).

Ответ 4

Это решит:

SELECT DISTINCT RAND() as rnd, [rest of your query] ORDER BY rnd;

Ответ 5

Использовать RAND (SEED). Из документов: "Если указан постоянный целочисленный аргумент N, он используется как начальное значение". (http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand).

В приведенном выше примере порядок результата всегда один и тот же. Вы просто меняете семя (351) и получаете новый случайный порядок.

SELECT * FROM your_table ORDER BY RAND(351);

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

Ответ 6

Не видя SQL, я бы предположил, что вы можете попробовать SELECT DISTINCT...