使用Redis构建简单的社交网站

第1关:创建用户与动态

任务描述

本关任务:实现创建新用户和创建新动态功能。

相关知识

为了完成本关任务,你需要掌握:1.redis基本命令,2.python基本命令。

redis基本命令

hget:从哈希中获取指定域的值。

 
  1. conn = redis.Redis()
  2. conn.hget("testhash", "field1")

执行结果:2

incr:将 key 中储存的数字值增一。

 
  1. conn = redis.Redis()
  2. conn.incr("testcount")

执行前:不存在 testcount 键。

执行后:

testcount 1

hset:将哈希中域 field 的值设为 value

 
  1. conn = redis.Redis()
  2. conn.hset("testhash", "field1", 2)
  3. conn.hset("testhash", "field2", 4)

执行前:

{'field1': '1'}

执行后:

{'field1': '2', 'field2': '4'}

hmset:同时将多个域-值对设置到哈希表中。

 
  1. conn = redis.Redis()
  2. conn.hmset("test_hash", {
  3. 'id': 1,
  4. 'name': 'educoder',
  5. 'age': 2,
  6. })

执行后:

{'age': '2', 'id': '1', 'name': 'educoder'}

hincrby:为哈希中指定域的值增加增量 increment,用于统计。

 
  1. conn = redis.Redis()
  2. conn.hincrby("testhash", "field1", 1)

执行前:

{'field1': '1'}

执行后:

{'field1': '2'}

pipeline:将多条命令按照先后顺序放进一个队列中,一般配合execute一同使用,原子性(atomic)地执行队列里的命令。

 
  1. conn = redis.Redis()
  2. pipe = conn.pipeline(True) # 事务开始
  3. pipe.incr("counter")
  4. pipe.incr("counter")
  5. pipe.incr("counter")
  6. pipe.execute() # 事务执行

执行结果:[1, 2, 3],通过下标即可获取对应命令的执行结果。

python基本命令

将字符串全小写化:

 
  1. 'Hello, Educoder'.lower()

执行结果:'hello, educoder'

返回当前时间的时间戳。

 
  1. time.time()

使用格式化拼接字符串:

 
  1. "My name is %s, I'm %i years old"%('educoder', 2)

执行结果:"My name is educoder, I'm 2 years old"

#!/usr/bin/env python  
#-*- coding:utf-8 -*-
import re  
import time  
import redis
conn = redis.Redis()
# 创建新用户  
def create_user(login_name, real_name):  
    # 请在下面完成要求的功能  
    #********* Begin *********#  
    login_name = login_name.lower()  
    if conn.hget("users", login_name):  
        return None
    uid = conn.incr("user:id")  
    pipe = conn.pipeline(True)  
    pipe.hset("users", login_name, uid)  
    pipe.hmset("user:%i"%(uid), {  
        'login_name': login_name,  
        'id': uid,  
        'real_name': real_name,  
        'followers': 0,  
        'following': 0,  
        'posts': 0,  
        'last_signup': time.time(),  
    })  
    pipe.execute()
    return uid  
    #********* End *********#
# 为用户创建新动态  
def create_post(uid, content):  
    # 请在下面完成要求的功能  
    #********* Begin *********#  
    pipe = conn.pipeline(True)  
    pipe.hget("user:%i"%(uid), 'login_name')  
    pipe.incr("post:id")  
    login_name, pid = pipe.execute()
    if not login_name:  
        return None
    pipe.hmset("post:%i"%(pid), {  
        'id': pid,  
        'uid': uid,  
        'content': content,  
        'posted': time.time(),  
        'user_name': login_name,  
    })  
    pipe.hincrby("user:%i"%(uid), 'posts')  
    pipe.execute()
    return pid  
    #********* End *********#  

第2关:处理用户关系

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import re
import time
import redis

conn = redis.Redis()

# 关注用户
def follow(uid, other_uid):
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if conn.zscore(fkey1, other_uid):
        return None

    now = time.time()
    pipe = conn.pipeline(True)
    pipe.zadd(fkey1, other_uid, now)
    pipe.zadd(fkey2, uid, now)
    following, followers = pipe.execute()

    posts = conn.zrevrange("profile:%s"%(other_uid), 0, 100, withscores=True)
    if posts:
        pipe.zadd("home:%s"%(uid), **dict(posts))

    pipe.hincrby("user:%s"%(uid), 'following', int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', int(followers))
    pipe.execute()

    return True

# 取消关注
def unfollow(uid, other_uid):
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if not conn.zscore(fkey1, other_uid):
        return None

    pipe = conn.pipeline(True)
    pipe.zrem(fkey1, other_uid)
    pipe.zrem(fkey2, uid)
    following, followers = pipe.execute()

    posts = conn.zrevrange("profile:%s"%(other_uid), 0, -1)
    if posts:
        pipe.zrem("home:%s"%(uid), *posts)

    pipe.hincrby("user:%s"%(uid), 'following', -int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', -int(followers))
    pipe.execute()

    return True

# 创建新用户
def create_user(login_name, real_name):
    login_name = login_name.lower()
    if conn.hget("users", login_name):
        return None

    uid = conn.incr("user:id")
    pipe = conn.pipeline(True)
    pipe.hset("users", login_name, uid)
    pipe.hmset("user:%i"%(uid), {
        'login_name': login_name,
        'id': uid,
        'real_name': real_name,
        'followers': 0,
        'following': 0,
        'posts': 0,
        'last_signup': time.time(),
    })
    pipe.execute()

    return uid

# 为用户创建新动态
def create_post(uid, content):
    pipe = conn.pipeline(True)
    pipe.hget("user:%i"%(uid), 'login_name')
    pipe.incr("post:id")
    login_name, pid = pipe.execute()

    if not login_name:
        return None

    pipe.hmset("post:%i"%(pid), {
        'id': pid,
        'uid': uid,
        'content': content,
        'posted': time.time(),
        'user_name': login_name,
    })
    pipe.hincrby("user:%i"%(uid), 'posts')
    pipe.execute()

    return pid

第3关:状态与信息流

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import re
import time
import redis

conn = redis.Redis()

# 获得主页时间线
def get_home_timeline(uid, page=1, count=30):
    # 请在下面完成要求的功能
    #********* Begin *********#
    post_ids = conn.zrevrange("home:%s"%(uid), 0, -1)

    pipe = conn.pipeline(True)
    for pid in post_ids:
        pipe.hgetall("post:%s"%(pid))

    return pipe.execute()
    #********* End *********#

# 发布动态并将动态推送给粉丝
def post(uid, content):
    # 请在下面完成要求的功能
    #********* Begin *********#
    pid = create_post(uid, content)
    if not pid:
        return None

    posted = conn.hget("post:%s"%(pid), "posted")
    conn.zadd("profile:%s"%(uid), pid, float(posted))
    followers = conn.zrange("followers:%s"%(uid), 0, -1)

    pipe = conn.pipeline(False)
    for follower in followers:
        pipe.zadd("home:%s"%(follower), pid, float(posted))
    pipe.execute()

    return pid
    #********* End *********#

# 关注用户
def follow(uid, other_uid):
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if conn.zscore(fkey1, other_uid):
        return None

    now = time.time()
    pipe = conn.pipeline(True)
    pipe.zadd(fkey1, other_uid, now)
    pipe.zadd(fkey2, uid, now)
    following, followers = pipe.execute()

    posts = conn.zrevrange("profile:%s"%(other_uid), 0, 100, withscores=True)
    if posts:
        pipe.zadd("home:%s"%(uid), **dict(posts))

    pipe.hincrby("user:%s"%(uid), 'following', int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', int(followers))
    pipe.execute()

    return True

# 取消关注
def unfollow(uid, other_uid):
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if not conn.zscore(fkey1, other_uid):
        return None

    pipe = conn.pipeline(True)
    pipe.zrem(fkey1, other_uid)
    pipe.zrem(fkey2, uid)
    following, followers = pipe.execute()

    posts = conn.zrevrange("profile:%s"%(other_uid), 0, -1)
    if posts:
        pipe.zrem("home:%s"%(uid), *posts)

    pipe.hincrby("user:%s"%(uid), 'following', -int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', -int(followers))
    pipe.execute()

    return True

# 创建新用户
def create_user(login_name, real_name):
    login_name = login_name.lower()
    if conn.hget("users", login_name):
        return None

    uid = conn.incr("user:id")
    pipe = conn.pipeline(True)
    pipe.hset("users", login_name, uid)
    pipe.hmset("user:%i"%(uid), {
        'login_name': login_name,
        'id': uid,
        'real_name': real_name,
        'followers': 0,
        'following': 0,
        'posts': 0,
        'last_signup': time.time(),
    })
    pipe.execute()

    return uid

# 为用户创建新动态
def create_post(uid, content):
    pipe = conn.pipeline(True)
    pipe.hget("user:%i"%(uid), 'login_name')
    pipe.incr("post:id")
    login_name, pid = pipe.execute()

    if not login_name:
        return None

    pipe.hmset("post:%i"%(pid), {
        'id': pid,
        'uid': uid,
        'content': content,
        'posted': time.time(),
        'user_name': login_name,
    })
    pipe.hincrby("user:%i"%(uid), 'posts')
    pipe.execute()

    return pid

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 好的,我明白了。关于你的问题,MySQL适合存储结构化数据,比如用户信息、订单、文章等等。而Redis适合存储非结构化数据,比如缓存数据、消息队列、分布式锁等等。此外,由于Redis拥有非常高的读写性能,可以用于构建高并发的缓存系统。希望这个回答能对你有帮助。 ### 回答2: 在选择使用MySQL还是Redis的情况下,需考虑到两者的特点及应用场景。 MySQL是一个关系型数据库管理系统,适用于处理结构化数据。它适用于数据之间有复杂关系、需要备份和恢复、涉及事务处理、需要强一致性的场景。MySQL可以存储大量数据,并支持复杂的查询和聚合操作,适用于数据量较大且需要进行复杂查询的应用。例如,电子商务平台通常需要处理大量用户和订单数据,使用MySQL更适合。 Redis是一个高性能的内存数据库,适用于处理非结构化或半结构化数据,并提供了丰富的数据结构,如字符串、哈希表、列表、集合和有序集合。Redis具有快速的读写速度和高并发性能,并且可以将部分数据持久化到硬盘上。适用于对数据访问速度要求较高的应用,如缓存、会话管理、排行榜和实时分析。例如,社交媒体应用通常需要快速读取用户关注和推荐用户,使用Redis更合适。 综上所述,使用MySQL适合于需要复杂查询、事务处理和强一致性的应用场景,而Redis适用于高性能、快速读写和对数据结构有特殊要求的应用场景。在实际应用中,可以结合两者的优势进行合理选择,如使用MySQL存储主要数据,将常用数据放入Redis缓存,以提高应用的整体性能和响应速度。 ### 回答3: MySQL和Redis是两种常用的数据库管理系统,它们适用于不同的场景和需求。 MySQL适用于以下情况: 1. 数据的一致性和持久性要求较高的场景,如金融系统、电子商务平台等需要严格的数据管理和保证的领域。 2. 需要复杂的查询和关系型数据操作的场景,如需要进行多表连接、嵌套查询、事务管理等的应用。 3. 数据量较大的场景,MySQL具有较好的扩展性和稳定性,能够应对大规模数据的存储和访问。 4. 需要使用SQL语言进行数据操作和管理的场景,MySQL是一种成熟的关系型数据库系统,提供了广泛的SQL支持。 Redis适用于以下情况: 1. 需要高性能的场景,如高并发访问、实时推送、缓存等应用,Redis具有快速读写速度和高并发处理能力。 2. 需要对数据进行快速操作和存储的场景,Redis将数据全部存储在内存中,读写速度远高于磁盘IO的数据库系统。 3. 需要对数据进行简单的操作和处理的场景,Redis不支持复杂的查询和事务操作,适合用于简单的键值对存储和操作。 4. 需要对大数据量进行计数、排行等操作的场景,Redis提供了丰富的数据结构和功能,如set、list、hash等,方便进行统计和计算。 综上所述,在选择数据库管理系统时,需根据实际的需求和场景来进行选择。如果需要复杂的查询和事务管理,以及对数据的持久性和一致性要求较高,则选择MySQL;如果对性能和简单的数据操作有较高的要求,或需要进行缓存和计算等操作,则选择Redis

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ଲଇଉକ ଲ ̊ଳ

多谢大哥赏赐

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

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

打赏作者

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

抵扣说明:

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

余额充值