Я делаю сайт, похожий на digg, который будет иметь домашнюю страницу с разными категориями. Я хочу отображать самые популярные материалы.
Наша рейтинговая система просто «нравится», например «Мне это нравится» и еще много чего. Мы в основном хотим отображать представления с наибольшим количеством «симпатий» за раз. Мы хотим иметь три категории: популярность во все времена, на прошлой неделе и в последний день.
Кто-нибудь знает способ помочь? Я понятия не имею, как это сделать и сделать его эффективным. Я думал, что мы могли бы использовать какую-то работу cron, чтобы работать каждые 10 минут и тянуть количество понравившихся за последние 10 минут … но мне сказали, что это довольно неэффективно?
Помогите?
Благодаря!
Обычно сайты, относящиеся к Digg и Reddit, относятся к дате представления, а не по времени голосования. Таким образом, все, что требуется, это простой SQL-запрос, чтобы найти верхние представления за X-период. Вот псевдо-запрос, чтобы найти 10 самых популярных ссылок за последние 24 часа, используя этот метод:
select * from submissions where (current_time - post_time) < 86400 order by score desc limit 10
В основном, этот запрос говорит, чтобы найти все материалы, в которых количество секунд между временем и временем его размещения составляет менее 86400, что составляет 24 часа в UNIX.
Если вы действительно хотите измерить популярность в течение X-интервала времени, вам нужно будет сохранить сообщение и время для каждого голосования в другой таблице:
create table votes ( post foreign key references submissions(id), time datetime, vote integer); -- +1 for upvote, -1 for downvote
Затем вы можете создать список наиболее популярных сообщений между X и Y раз так:
select sum(vote), post from votes where X < time and time < Y group by post order by sum(vote) desc limit 10;
Отсюда вы просто прыгаете, пропускаете и внутренне присоединяетесь от получения данных сообщения, привязанных к возвращенным идентификаторам.
У вас есть достойная настройка БД? Можем ли мы слышать о ваших деталях и индексах CREATE TABLE
? Предполагая разумную настройку, БД должна быть в состоянии вытащить счета, которые вам потребуются достаточно быстро, чтобы удовлетворить ваши потребности! Например (без индексов и ключей, которые несколько зависят от того, какой механизм БД вы используете), учитывая две таблицы:
CREATE TABLE submissions (subid INT, when DATETIME, etc etc) CREATE TABLE likes (subid INT, when DATETIME, etc etc)
вы можете получить топ-33 всенародных популярных материалов, как
SELECT *, COUNT(likes.subid) AS score FROM submissions JOIN likes USING(subid) GROUP BY submissions.subid ORDER BY COUNT(likes.subid) DESC LIMIT 33
и те, кто голосовал в течение определенного периода времени, как
SELECT *, COUNT(likes.subid) AS score FROM submissions JOIN likes USING(subid) WHERE likes.when BETWEEN initial_time AND final_time GROUP BY submissions.subid ORDER BY COUNT(likes.subid) DESC LIMIT 33
Если вы сохраняете «голоса» (положительные или отрицательные) в likes
, вместо того, чтобы просто подсчитывать каждую запись там как +1
, вы можете просто использовать SUM(likes.vote)
вместо COUNT
.
Для стабильного списка, такого как alltime, lastweek, потому что они не должны меняться очень быстро, поэтому я думаю, что вы должны сохранить список в кеше с истечением срока действия около 1 дня или дольше.
Если вы относитесь к правильному счету в реальном времени, вы можете проверить его на каждом просмотре страницы, сравнив страницу с самой низкой страницей в кеше.
Все, что вам нужно сделать, – это обеспечить синхронизацию между кешем и фактической базой данных.
thethanghn
Запросы, в которых порядок является некоторой функцией текущего времени, могут стать реальными проблемами производительности. Все становится намного проще, если вы можете ведро по календарному времени и обновлять баллы для каждого ведра, когда люди голосуют.
Чтобы не ответить никому, я бы посоветовал вам прочитать документацию (если вы, конечно, используете MySQL).