2009-06-22 3 views
12

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

Наша рейтинговая система просто «нравится», например «Мне это нравится» и еще много чего. Мы в основном хотим отображать представления с наибольшим количеством «симпатий» за раз. Мы хотим иметь три категории: популярность во все времена, на прошлой неделе и в последний день.

Кто-нибудь знает, как помочь? Я понятия не имею, как это сделать и сделать его эффективным. Я думал, что мы могли бы использовать какую-то работу cron, чтобы работать каждые 10 минут и тянуть количество понравившихся за последние 10 минут ... но мне сказали, что это довольно неэффективно?

Помощь?

Спасибо!

ответ

9

Обычно сайты с 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; 

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

+1

Я писал в основном то же самое, вы были быстрее меня. =) –

+1

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

-1

Чтобы ответить на вопрос nobody_, я бы посоветовал вам ознакомиться с documentation (если вы используете MySQL, конечно).

3

У вас есть достойная настройка БД? Можем ли мы рассказать о ваших CREATE TABLE деталях и индексах? Предполагая разумную настройку, БД должна быть в состоянии вытащить счета, которые вам потребуются достаточно быстро, чтобы удовлетворить ваши потребности! Например (за вычетом индексов и ключей, которые в некоторой степени зависят от того, что DB двигатель вы используете), учитывая две таблицы:

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 s.

0

Для стабильного списка как alltime, lastweek, потому что они не должны меняться очень быстро, поэтому я думаю, что вы должны сохранить список в кеше с истечением срока действия около 1 дня или дольше.

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

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

thethanghn

+0

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

0

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

Смежные вопросы