redis实战(3):对文章进行投票

实战系列都是需求+伪代码;

1 需求

如果一个文章获得200+票(up vote),则是一篇有趣的文章;假如每天发布1k文章,其中50篇是有趣的文章,则把这50篇放到文章列表的前100位,至少一天。


2 设计

为了产生一个能够随着时间流逝而不断减少的的评分,设计规则:文章票数 * 常量 + 文章发布时间 = 文章评分

假设常量 = 432 = 86400(一天的 秒数) / 200(有趣文章票数的阀值)

除了存储文章评分,还要存储文章的一些其他信息,设计使用hash存储如下
在这里插入图片描述

文章的投票文章使用2个有续集合有序的存储文章:

  • 第一个有序集合的成员:文章ID,分值是文章的发布时间;
  • 第二个有序集合的成员:文章ID,分值为文章的评分;

在这里插入图片描述

通过上面2个有序集合,网站既可以根据文章发布时间的先后顺序展示文章,又可以根据文章的评分高低展示文章;

为了防止用户对同一篇文章多次投票,需要记录一个已经投票的用户名单,为了尽量节省内存,规定:一篇文章发布期满一周后,用户不能对其投票;文章的评分将被固定,记录文章投票用户的集合也会被删除;
在这里插入图片描述
展示当115423号用户给100408号文章投票流程

  1. 100408文章得到一张支持票,它的评分增加了
    在这里插入图片描述

  2. 115423号用户加入到“100408号文章投票用户”集合中
    在这里插入图片描述

3 伪代码实现

已经设计好评分的方法,也设计了数据结构。现在理一理流程
当用户尝试投票时候,代码用zscore查询“文章发布时间的zset”,如果发布时间查过一周,可以投票(将用户加入“已投票用户set”),如果添加成功,说明用户第一次对改文章投票,代码使用zincryby对文章加432分。并用hincryby 对 散列结论的文章投票数量进行更新(hincrby命令用户对散列存储的值执行自增操作)

public static Integer ONE_WEEK_IN_SCORE= 7*86400; //一周有效期
public static Integer VOTE_SCORE =432 ;

public void articleVote(conn, user, article){
	timeBtw = now.time() - ONE_WEEK_IN_SCORE; //获取时间差,看是否可以继续投票
	// 判断是否还可以对文章进行投票
	if(conn.zscore(‘time:’,article) < timeBtw){
		return
	}
	articleId= article.partition(":")[-1] //从 article:id标识符中取出文章ID
	
	//事务开始
	conn.sadd('voted:'+articleId,user)
	conn.zincryby('score:',article,VOTE_SCORE )
	conn.hincryby(article,"votes",1)
	//事务结束
}

相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页