Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вывод рандомных столбцов из MySQL 
:(
    Опции темы
Nigel
Дата 24.12.2008, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


познаю мир
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 20.11.2007

Репутация: 7
Всего: 19



Что-то типа такого
Код

select * from `table` where id>(select floor(max(id)*rand()) from `table`) limit 10;

Конечно, нужен ключ по полю id.
PM MAIL   Вверх
bars80080
Дата 24.12.2008, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



меня тут осенила гениальнейшая идея на ноб.премию

смотрю, как тут не первый раз возникают темы про случайную выборку и про то, насколько она тормознутая средствами mysql и подумалось следующее

как бы мы там ни говорили про идеальность, всё равно её не существует, если мы говорим о "случайном" выборе, то на самом деле подразумеваем псевдослучайную последовательность, которая периодически повторяется, но с большим периодом. в конце концов в электронике нет генератора чистой случайности за исключением болометра

итак, вместо того чтобы пользоваться rand можно сконструировать псевдослучайный режим выборки, скажем, так:
условия: при всём уважении, если мы поднимаем что-то, к примеру случайные фотографии или набор новостей, то больше 20-40 смысла нет
отсюда, можно ввести в таблицу поле rnd int в которое при запросах insert и update будет вноситься случайное число. далее, при необходимости случайной выборки мы средствами пхп случайно определяем два-три числовых параметра. допустим: дата, число rnd int и в какую сторону считать выше или ниже. после этого строим запрос по принципу: 

... where date<$rnd_date and rnd>$rnd_int order by rnd desc limit 20

синим и красным отмечены случайные элементы. если элементов не хватает, то надо просто отсчитать в другую сторону, костыль придумать не сложно

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




вот такое вот идея  smile 
PM MAIL WWW   Вверх
skyboy
Дата 24.12.2008, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Nigel, однако в вырожденном случае(rand() вернуло 1) мы получим выборку из одной записи. сколько бы ни было в таблице. естественно, в реальности все может быть, но поначалу(пока в таблице данных немного) такая накладка вполне может частенько происходить: нужное количество есть, но выводятся не все.
PM MAIL   Вверх
Nigel
Дата 24.12.2008, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


познаю мир
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 20.11.2007

Репутация: 7
Всего: 19



skyboy, http://dev.mysql.com/doc/refman/5.1/en/mat...l#function_rand в неравенстве строго меньше 1.
PM MAIL   Вверх
skyboy
Дата 25.12.2008, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Nigel, окей. 9 записей всего. надо выбрать максимум 10 случайных. rand() возвращает 0,5. сколько записей из списка id (1,2,3,4,5,6,7,8,9) будет возвращено? готов поспорить, что 5(id: 5,6,7,8,9). Это не то, что десять требуемых, а даже не девять имеющихся. 
итак, продолжим измышления.
пускай, у нас значения id распределены так:
1,2,3,4,5,6,7,8,9,100
вероятность того, что floor(rand() * 100) будет больше 9 высока - 9/10. То есть вероятность 90%, что вместо хотя бы 9 значений будет получено только одно.
или я что-то неверно понимаю?

Добавлено через 2 минуты и 51 секунду
нет, вариантов вижу два: выбрать id в клиента и средствами клиента перемешать/выбрать N требуемых или же "тот самый неэффективный запрос с order by rand()". впорчем, не все так плохо: можно поле "случайное значение для сортировки" записывать в таблицу и обновлять...эээ..ну, раз в час. тогда и индексы используются, и элементы местами меняются, да и клиенты вполне могут не заметить.
PM MAIL   Вверх
Nigel
Дата 25.12.2008, 02:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


познаю мир
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 20.11.2007

Репутация: 7
Всего: 19



Выбрать 10 записей из 9 возможных? Это как? Опечатка, видимо smile 

skyboy, order by rand() начинает тормозить на 4-5 тыс записях, поэтому приводить в пример таблицу с 5-ю, 10-ю или 20-ю записями не коректно. Примерно из той же оперы: у меня таблица с 3-мя записями, при выборке мускул подлец индексы не использует, щас я ему форс пропишу, чтоб было как надо. 
Цитата(skyboy @  25.12.2008, 00:37)

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

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

Это сообщение отредактировал(а) Nigel - 25.12.2008, 02:52
PM MAIL   Вверх
skyboy
Дата 25.12.2008, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Nigel, сложно возразить. 
Да, приведенный тобой запрос быстрее.
Да, таблица с пятью записями маловероятно появится в реальном проекте. 
Но, с другой стороны:
- если имеется значительная "дырка" в значениях поля id(массовая чистка контента портала, удаление тестовых данных), то данные, с идентификатором "до дырки" будут выбираться значительно реже тех, что "после дырки"
- данные будут идти подряд(в смысле, выбираются идентификаторы, идущие подряд) - разве это больший "рэндом", чем обновление каждый час?
впрочем, да. согласен. в реальном проекте разработчика должна волновать производительность запроса на 5 тысячах записей, нежели корректность работы.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0562 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.