Комментарии 17
Это называется — «нечего делать? Собери велосипед!»
Первая ссылка из гугла по запросу «mysql rand приоритет»
www.sql.ru/forum/actualthread.aspx?tid=323828
Вкратце:
… ORDER by (RAND()*priority_column)
Первая ссылка из гугла по запросу «mysql rand приоритет»
www.sql.ru/forum/actualthread.aspx?tid=323828
Вкратце:
… ORDER by (RAND()*priority_column)
А если 100 000 элементов и нужно выбрать одну запись — для всех RAND генерировать?
Для количества объектов, что указал ТС, это нормально.
я указал только пример, глупо было бы писать 100 000 объектов для примера… вы господин очень буквально все понимаете
Допустим.
Про велосипед. В том же мускульном мануале где-то говорится, что типа если вам нужно выбрать одну запись из огромного числа, лучше сгенерируйте номер айдишника и запросите его напрямую.
Решение ТС наводит на размышления, не такой уж велосипед.
Про велосипед. В том же мускульном мануале где-то говорится, что типа если вам нужно выбрать одну запись из огромного числа, лучше сгенерируйте номер айдишника и запросите его напрямую.
Решение ТС наводит на размышления, не такой уж велосипед.
Если в БД 100 000 элементов и вы будете использовать вариант предложенный ТС-ом, то сервер точно лопнет
ок мистер умник, а если база данных не mysql и объекты просто находятся в системе??? Или даже если база и есть, но база не умеет?
Гляда на такие комменты вспоминается отрывок из Звездного пути, где Арчера забросило в будующее после глобальной войны и все разрушено. И они пытались создать какуюто штуку для передачи данных в прошлое. Там прозвучала такая фраза «Зачем мне было знать его устройство, в наше время они на каждой парте стоят».
Да круто что ты знаешь что есть такая функция, а ты знаешь как она работает?
Гляда на такие комменты вспоминается отрывок из Звездного пути, где Арчера забросило в будующее после глобальной войны и все разрушено. И они пытались создать какуюто штуку для передачи данных в прошлое. Там прозвучала такая фраза «Зачем мне было знать его устройство, в наше время они на каждой парте стоят».
Да круто что ты знаешь что есть такая функция, а ты знаешь как она работает?
Прекрасно знаю. При написании комментария опирался на то, что вы указали субд mysql.
О том, что такое случайная величина и как получить требуемое распределение из равномерного рассказывают на лекциях по теории вероятности. В любом случае построить отрезок из интервалов, соответствующих коэффициенту ротации, и взять rand() на этом отрезке проще, чем городить массивы. Причём можно сделать так, что при показе баннера надо будет сделать только 2 запроса, и оба по PK. Апдейтить коэффициенты, правда, будет чуть сложнее. По сложности можно уложиться в log(n), так что 100 000 записей не страшно.
Ещё один вариант — построить индекс по полю коэффициента, а коэффициенты хранить в виде суммы всех предыдущих + коэффициент текущей записи. Тогда 1 запрос даёт максимальный коэффициент (это 1 проход по индексу), потом запрос типа where k > rand(max_k) limit 1 ещё раз пройдётся по индексу и вернёт нужную запись. Сложность этого алгоритма log(n) (т.к. есть индексы, а индексы — деревья), что вполне приемлемо. Удалять записи опять будет немного сложно, зато вся логика в базе.
Ещё один вариант — построить индекс по полю коэффициента, а коэффициенты хранить в виде суммы всех предыдущих + коэффициент текущей записи. Тогда 1 запрос даёт максимальный коэффициент (это 1 проход по индексу), потом запрос типа where k > rand(max_k) limit 1 ещё раз пройдётся по индексу и вернёт нужную запись. Сложность этого алгоритма log(n) (т.к. есть индексы, а индексы — деревья), что вполне приемлемо. Удалять записи опять будет немного сложно, зато вся логика в базе.
немного не понял часть where k > rand(max_k) limit 1… первым запросом мы же просто берем максимум… тоесть получается k > max_k или я что то не догнал?
Нет. Коэффициент ротации надо хранить в виде верхней границы, т.е.:
У баннеров 1,2 и 4 в этом случае коэффициент ротации 10, а у баннера 3 — 20. Из неудобств: при удалении баннера или изменении коэффициентов надо будет пересчитывать цифирки. Из удобств: работать будет быстро. Если куда нибудь ещё кэшировать максимум — то совсем быстро будет работать, за log(n).
В синтаксисе MySQL rand() должен выглядеть так:
Можно хранить нижнюю границу и тогда сравнивать k > ...., не суть важно, на скорость не влияет.
name k_orig k
banner1 10 10
banner2 10 20
banner3 20 40
banner4 10 50
У баннеров 1,2 и 4 в этом случае коэффициент ротации 10, а у баннера 3 — 20. Из неудобств: при удалении баннера или изменении коэффициентов надо будет пересчитывать цифирки. Из удобств: работать будет быстро. Если куда нибудь ещё кэшировать максимум — то совсем быстро будет работать, за log(n).
В синтаксисе MySQL rand() должен выглядеть так:
SELECT * FROM banners where k < FLOOR(RAND() * (max_k + 1));
Можно хранить нижнюю границу и тогда сравнивать k > ...., не суть важно, на скорость не влияет.
А можно просто нагенерить в таблицу очередь, в которой будут воспроизводиться банеры. И последовательно выбирать следующий элемент. Тех банеров которых больше можно чаще вставить в эту очередь.
А случайность в такой выборке может быть и не нужна, пользователи своими запросами сами ее создадут (в случае если пользователей все же больше одного).
А случайность в такой выборке может быть и не нужна, пользователи своими запросами сами ее создадут (в случае если пользователей все же больше одного).
это собственно и есть мой второй вариант. Просто без последнего рандома.
И хватит уже обсуждать это банерами. Абстрагируйтесь. На самом деле я писал это далеко не для банеров
И хватит уже обсуждать это банерами. Абстрагируйтесь. На самом деле я писал это далеко не для банеров
По тексту понял что вы сначала выбираете ротационную таблицу, а затем достраиваете массив дублями объектов в зависимости от рейтинга.
Я же предлагаю сразу в качестве ротационной таблицы хранить очередь показов со всеми дублями, и выбирать последовательно элементы, возложив рандомизацию на плечи пользователей.
Если что-то не так понял в вашей статье — прошу извинить.
Я же предлагаю сразу в качестве ротационной таблицы хранить очередь показов со всеми дублями, и выбирать последовательно элементы, возложив рандомизацию на плечи пользователей.
Если что-то не так понял в вашей статье — прошу извинить.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Проектирование алгоритма ротатора по рейтингу