redis(二、实现投票功能)

写在前面的话:最近出于提升自己技术能力的考虑,准备系统的学习一下redis。这里主要是一个记录收获以及摘录干货的作用。学习书籍为《redis 实战》。不感兴趣的战友不必勉强阅读。

现在很多的网站,比如简书,都有提供对文章进行点赞等投票性质的功能。某种场景下,网站会根据文章的发布时间以及文章获得的投票数量来计算出一个评分,然后根据这个评分来决定如何排序和展示文章。而要构建一个这样的文章投票网站,我们首先要做的就是为这个网站设置一些数值和限制条件:如果一篇文章获得了超过200张投票,那么网站就认为这是一篇值得推荐的文章;假如网站每天有1000篇文章发布,而有50篇文章达到了这个要求,那么网站会把这50篇文章放到文章列表的前100位至少一天。

为了产生一个能够随着时间流逝不断减少的评分,程序需要根据文章的发表时间和当前的时间来计算评分。具体做法是: 将文章得到的投票数乘以一个常量,再加上文章的发布时间,得到的结果即为评分。在这里我们将常量设为432.因为一天为86400秒,投票的门槛数是200,它们的比值即为432.这样的话,文章每获得一张投票,评分即增加432分。我们除了计算文章的评分之外,还要使用redis来有序的存储网站文章的各种信息。在这里,对于每篇文章,我们使用散列(hash)来存储它的标题,发表时间,作者,文章url,以及获得的投票数等。另外,正对网站的所有文章,我们还需要两个有序集合(zset)来存储文章:第一个有序集合,成员为文章ID,分值为发布时间;而第二个有序集合成员同样为文章ID,但是分值为文章的评分。这样的话,网站既可以按照发布时间的先后来展示文章,也可以按照文章的评分(受欢迎程度)来展示文章。

为了防止重复投票,我们还要为每篇文章记录一个已投票用户的名单。所以,程序将为每篇文章创建一个集合,用来存储已投票用户的ID,为了 解决内存,我们还应当规定,当一篇文章发布超过一个月(或者你认为的合适的时间长度),用户将不能再对文章进行投票。同时文章评分将被固定,而记录文章已投票用户名单的集合也就可以删除了。

ok,到了这里我们的准备工作就已经做好了。接下来就是具体利用redis的各类函数去实现投票的功能了。当然这里主要是写思路。做程序的本质就是用代码把你的想法给实现出来。所谓的程序有bug,无非就是你考虑的问题不全面,当系统面对你没有预设好处理方案的问题时,就会报错。

投票

当用户尝试对某篇文章进行投票时,程序会先使用zscore命令去检查记录这篇文章发布时间的有序集合,如果未超过一个月,那么程序将使用sadd命令将用户添加到记录这篇文章已投票用户名单的集合里。如果添加操作成功,说明这个用户是第一个给这篇文章投票,系统会继续使用Zincrby命令为这篇文章评分增加432评分;并使用Hincrby命令对在散列(hash)中记录的文章投票数进行自增+1。在这一系列的操作里,为了保证数据的一致性,sadd,zincrby,hincrby三个命令是需要放到一个事务里的。

发布文章

发布文章需要先创建一个文章ID,这项工作可以通过对一个计数器进行自增为1的操作来实现。接着程序需要使用sadd命令将文章发布者的ID添加到记录这篇文章已投票用户的集合里(是的,每篇文章默认作者会给自己投一票~),并使用expire命令为这个集合设置一个过期时间,让redis可以在到期后自动删除这个集合。之后,系统还需要调用Hmset命令来存储文章的相关详情信息,并执行两个Zadd命令,将文章的初识评分和发布时间分别存到两个有序集合里。这样,文章的发布就实现了。

排序文章

那么接下来就要考虑怎样取出评分最高的文章或者最新发表的文章了。为实现这两个功能,系统需要先使用ZREVRANGE命令取出多个文章ID,然后再对每个ID执行一次HGETALL命令来取出文章的详情。然后根据详情里的评分数值或者发布时间,我们就可以获得评分最高或者最新发布的文章。需要特别注意的是,有序集合会根据成员的分值从小到大去排列元素,所以要使用ZREVRANGE命令,以‘从大到小’的排列顺序来取数据才是正确的做法。

文章分组

另外一个非常实用的功能是文章分类显示。这个功能可以让用户只看到与特定话题相关的文章。群组功能有两个部分组成,一个部分负责记录文章属于哪个群组,另一个负责取出群组里的文章。为了记录各个群组都保存了哪些文章,网站需要为每个群组都创建一个集合,并将所有属于同一群组的文章ID都记录在群组里。而为了能够根据评分对群组文章进行排序和分页,所有的文章也要按照分值大小有序的存到一个有序集合里。redis的ZINTERSTORE命令可以接受多个集合和多个有序集合作为输入,然后找出他们的交集。并合并成员的分值(所有的集合成员的分值默认为1),最后以合并后的成员分值进行排序。这样,通过对存储群组文章的集合和存储文章评分的有序集合执行ZINTERSTORE命令,我们可以得到按照文章评分排序的文章群组;而通过对存储群组文章的集合和存储文章发表时间的有序执行ZINTERSTORE命令,我们可以得到按照文章发表时间排序的文章群组。【注意:当群组较大时,执行ZINTERSTORE命令会较费时。为了减少redis的工作量,可以考虑加上缓存。每次系统尝试去计算交集结果时,可以先去缓存中拿数据】

感悟:在学习redis时,还是要先自我屏蔽一下之前使用关系型数据库时的固化思维。然后深刻理解redis的五种数据类型的特点,才能真正上手redis。没有人可以在第一时间就把代码写的非常健壮。总是要随着业务场景的复杂而去迭代我们的函数。但是经验可以解决九成以上的bug,所以,代码还是要多敲,大咖们的代码也是要多去阅读。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,401评论 25 707
  • 当然孤单,是值得享受的孤单 国庆假期,一个人去了一趟山东,烟台和威海两座城市。去山东,自然是为了看海,但是旅游(或...
    桃籽霁阅读 671评论 2 4
  • 在政治课本上看到那么一句话,“宏观物体是机械运动的载体”,看起来与你毫无关联,我却不可避免地想起了你。 窗外的...
    小北姐姐阅读 179评论 0 0
  • 作为2016级的大一新生,第一堂课就是避之不及的军训。 我在厦门。曾经的一条“你若军训,便是晴天”的亘古不变的...
    epinghong阅读 174评论 0 0
  • 文/喵先生 爱上一只猫 喜欢她柔顺的毛发 匀称标致的身材 最美丽的是 那双不羁的眼眸 我们同在风雨中长大 每日为我...
    袁豪杰阅读 149评论 0 0