流行度算法

12

我正在制作一个类似digg的网站,主页将有不同的分类。我想展示最受欢迎的提交。

我们的评级系统仅为“喜欢”,如“我喜欢这个”之类。基本上,我们希望按时间显示获得“喜欢”数量最多的提交。我们想要三个类别:历史总人气,上周和昨天。

有人知道如何帮忙吗?我不知道如何处理并使其有效率。我认为我们可以使用某种定时任务每10分钟运行一次,并获取最近10分钟内每个提交的“喜欢”数量...但是我被告知这非常低效?

求助?

谢谢!

5个回答

9

通常类似于Digg和Reddit的网站按照提交日期而不是投票时间排序。这样,只需要一个简单的SQL查询就可以找到X时间段内的十个最受欢迎的提交内容。以下是使用此方法查找过去24小时内最受欢迎的10个链接的伪查询:

select * from submissions
 where (current_time - post_time) < 86400
 order by score desc limit 10

基本上,这个查询的意思是查找所有提交的内容,其中现在时间和发布时间之间的秒数小于86400,即UNIX时间下的24小时。

如果您真的想在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;

从这里开始,你只需要一步之遥,即内部连接,就可将返回的 id 与 post 数据关联起来。


1
我也在写基本相同的东西,你比我快。=) - Alix Axel
1
非常好的答案...看起来虽然你描述的第一种方法更简单,但它无法处理过去发布的某些内容突然重新流行的情况(可能是由于最近的新闻事件或其他原因)?第二种方法看起来更健壮,谢谢,我会尝试一下! - Brian Armstrong

3

您的数据库设置良好吗?我们可以了解一下您的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来计算。

0

对于像alltime、lastweek这样的稳定列表,因为它们不应该变化得非常快,所以我认为你应该将列表保存在缓存中,并设置过期时间为1天或更长。

如果你关心实时正确计数,可以通过将页面与缓存中最低页面进行比较,在每个页面视图中检查。

你需要做的就是关注缓存和实际数据库之间的同步。

thethanghn


我的方法的目标是尽可能减少数据库查询,因为您不需要每次都从数据库获取顶部。 - thethanghn

0

查询中如果排序是当前时间的某个函数,可能会成为真正的性能问题。如果您可以按日历时间进行分桶,并在每个分桶中根据人们的投票更新得分,则情况会变得简单得多。


...嗯...什么? - Just a coder

-1
为了补充nobody_的回答,我建议你阅读文档(如果你正在使用MySQL的话)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接