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)
	//事务结束
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

water___Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值