来自《Redis 实战》第一章

对于 Redis 数据结构类型及使用不太清楚的可以参考 此链接

需求:

  1. 网站需要根据文章的发布时间和文章获得的投票数量计算出一个评分,然后按照这个评分来决定如何排序和展示文章。
  2. 得分的计算方式为:将文章得到的支持票数乘以一个常量(假设为432),然后加上文章的发布时间(定为从1970年1月1日到现在经过的秒数),得出的结果就是文章的评分。
  3. 同时需要提供既能按照发布时间来展示文章,又能根据评分来展示文章的功能。
  4. 如果文章发布超过一周,则不提供投票功能。

Redis 中结构设计:

文章信息
value 结构 HASH
key article:<文章id>   例:article:100408 (使用冒号来区分名字的不同部分,100408为文章ID)
value 保存的键值对包含 标题、链接、发布者、发布时间、得票数 信息
文章发布时间信息
value 结构 ZSET
key time:
value

成员为 article:<文章id>   分值为 1997年1月1日到现在的秒数

例:article:100408 (成员) - 1332065474.47 (分值)

文章评分信息
value 结构 ZSET
key score:
value

成员为 article:<文章id>   分值为 文章评分

例:article:100408 (成员) - 13320656524.47 (分值)

投票记录信息
value 结构 SET
key voted:<文章id> 例:voted:100408
value user:<用户id> 例:user:234487

Python 实现的代码

import time

ONE_WEEK_IN_SECONDS = 7 * 24 * 60 * 60
VOTE_SCORE = 432
ARTICLES_PER_PAGE = 25 '''
用户对文章进行投票(目前没有考虑事务问题)
用户尝试投票时,使用 ZSCORE 命令检查记录文章发布时间的有序集合,判断文章的发布时间是否未超过一周,
如果仍可投票,使用 SADD 命令,尝试将用户添加到 记录文章已投票用户名单的集合里面,
如果成功,说明此用户是第一次为这个文章投票,此时使用 ZINCRBY 命令为文章添加 432 的评分数,
并使用 HINCRBY 命令对散列记录的文章投票数量进行更新
'''
def article_vote(conn, user, article):
# 计算投票的截止时间
cutoff = time.time() - ONE_WEEK_IN_SECONDS
if conn.zscore('time:', article) < cutoff:
# 超过投票截止时间则直接返回
return
# 获取文章 ID 部分
article_id = article.partition(':')[-1]
# 尝试将投票用户添加到文章已投票用户集合中
if conn.sadd('voted:' + article_id, user):
# 为文章添加评分
conn.zincrby('score:', article, VOTE_SCORE)
# 更新文章的得票数(+1)
conn.hincrby(article, 'votes', 1) '''
发布文章
通过对一个计数器执行 INCR 命令来生成文章id,
接着使用 SADD 将文章发布者的id 添加到记录文章已投票用户名单的
集合里面(这个集合需要使用 EXPIRE 命令设置为一周的过期时间,因为只有一周内的文章可以投票),
之后使用 HMSET 命令来存储文章的相关信息,并执行两个 ZADD 命令,
将文章的初始评分和发布时间分别添加到两个相应的有序集合里面
'''
def post_article(conn, user, title, link):
# 通过自增方式生成文章 ID
article_id = str(conn.incr('article:'))
# 生成并添加对文章投票的用户信息,同时设置过期时间
voted = 'voted:' + article_id
conn.sadd(voted, user)
conn.expire(voted, ONE_WEEK_IN_SECONDS)
# 存储文章信息
now = time.time()
article = 'article:' + article_id
conn.hmset(article, {
'title': title,
'link': link,
'poster': user,
'time': now,
'votes': 1,
})
# 保存文章发布时间及评分信息
conn.zadd('score:', article, now + VOTE_SCORE)
conn.zadd('time:', article, now)
return article_id '''
获取指定排序后的文章信息
使用 ZREVRANGE 取出多个文章id, 再对每个文章id 执行一次 HGETALL 来取出文章的详细信息
'''
def get_articles(conn, page, order='score:'):
start = (page - 1) * ARTICLES_PER_PAGE
end = start + ARTICLES_PER_PAGE - 1
# 逆序(从大到小)获取数据
ids = conn.zrevrange(order, start, end)
articles = []
for id in ids:
article_data = conn.hgetall(id)
article_data['id'] = id
articles.append(article_data)
return articles

Redis 练习(一)的更多相关文章

  1. 使用redis构建可靠分布式锁

    关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...

  2. Ignite性能测试以及对redis的对比

    测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...

  3. mac osx 安装redis扩展

    1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis   ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...

  4. Redis/HBase/Tair比较

    KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式    支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...

  5. Redis数据库

    Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...

  6. redis 学习笔记(2)

    redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...

  7. redis 学习笔记(1)

    redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...

  8. python+uwsgi导致redis无法长链接引起性能下降问题记录

    今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...

  9. nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)

    本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...

  10. windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)

    本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...

随机推荐

  1. Openwrt 路由器上 安装 svn server

    Openwrt 上也可以搭建 svn 服务了,这样就不用开着 ubuntu 了,省电. 在后台打开 ssh 服务,或者使用 telnet 服务,使用 putty 登录路由器. 如下图所示,这里刷的是 ...

  2. 结题报告--P2441角色属性树

    题目:点此 题目描述 绪萌同人社是一个有趣的组织,该组织结构是一个树形结构.有一个社长,直接下属一些副社长.每个副社长又直接下属一些部长……. 每个成员都有一个萌点的属性,萌点属性是由一些质数的萌元素 ...

  3. Django_orm

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

  4. Python操作系统

    一 为什么要有操作系统 (两本书:现代操作系统.操作系统原理,学好python以后再去研究吧~~) 现代的计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,打印机,网络接口及其他输 ...

  5. tempdb 日志文件增长的问题

    前两天在一个客户那里发现tempdb log 文件增长很大,已经使用40GB了,而tempdb log 文件总的分配空间是70GB,并且日志空间貌似不能重用,他们使用sql 2012 打的sp4补丁, ...

  6. 【Weiss】【第03章】练习3.21:单数组模拟双栈

    [练习3.21] 编写仅用一个数组而实现两个栈的例程.除非数组的每一个单元都被使用,否则栈例程不能有溢出声明. Answer: 很简单,一个栈从数组头起,一个栈从数组尾起,分别保留左右栈头索引. 如l ...

  7. C#中无边框窗体拖动

    //定义一个bool变量标识是否拖动窗体 private bool isMove = false; //记录鼠标的位置 private Point point; 定义的变量 /// <summa ...

  8. JAVA-迭代器\增强型for循环。(新手)

    //导入的包.import java.lang.reflect.Array;import java.util.*;//创建的一个类.public class zylx1 { //公共静态的主方法. p ...

  9. Axure rp8 注册码,亲测可以用! 可用给个赞呗!!

    License:zdfans Key:fZw2VoYzXakllUuLVdTH13QYWnjD6NZrxgubQkaRyxD5+HNMqdr+WZKkaa6IoE5N

  10. wxPython4.0.4关于我们

    源码地址:https://download.csdn.net/download/zy0412326/12154342 wxPython4改版后将AboutBox方特到adv包里面.如果想快速实现GUI ...