Redis与python交互

Redis与Python交互

一、安装

pip install redis

二、使用

1. 连接

'''
python 操作redis的连接
'''

import redis
# 创建数据库连接对象
r = redis.Redis(host="127.0.0.1", port=6379, db=0, password="123456")

#查看所有key:[b'mylist', b'0', b'mylist1', b'mylist2']
print(r.keys("*"))

#查看键类型type:b'none'
print(r.type("age"))

#判断键是否存在:返回值 0或1
print(r.exists("spider::urls"))

#删除key
r.delete("name")

3. 操作列表

'''
python 操作redis的列表
'''

import redis

r = redis.Redis(host="127.0.0.1", port=6379, db=0, password="123456")

#lpush rpush
r.lpush("python:chancey", "Socket", "PythonWeb", "PythonSpider")
r.rpush("python:chancey", "HTML")

#l_range
print(r.lrange("python:chancey", 0, -1))

#从列表尾部弹出一个元素
r.rpop("python:chancey")
print(r.lrange("python:chancey", 0, -1))

#从列表头部弹出一个元素
r.lpop("python:chancey")
print(r.lrange("python:chancey", 0, -1))

#从列表尾部插入三个元素:CSS、JavaScript、jQuery
r.rpush("python:chancey", "CSS", "JavaScript", "jQuery")
print(r.lrange("python:chancey", 0, -1))

#删除下标为2的元素
r.lrem("python:chancey", 1, r.lindex("python:chancey", 2))
print(r.lrange("python:chancey", 0, -1))

#保留列表中的前2个元素
r.ltrim("python:chancey", 0, 1)
print(r.lrange("python:chancey", 0, -1))

#把下标为0的元素设置为redis
r.lset("python:chancey", 0, "redis")
print(r.lrange("python:chancey", 0, -1))

#在redis元素后边插入1个元素:AI
r.linsert("python:chancey", "after", "redis", "AI")
print(r.lrange("python:chancey", 0, -1))

#获取列表长度
print(r.llen("python:chancey"))

r.delete("python:chancey")

案例:一个进程负责生产URL、一个进程负责访问URL

'''
生产者,负责生产URL
'''

import redis
import random
import time

r = redis.Redis(host="127.0.0.1", port=6379, db=0)

#生成很多个URL,放进reids列表
for i in range(1, 101):
    url = "https://www.sina.com.cn/?page=" + str(i)
    # 放到redis列表
    r.lpush("spider:urls", url)
    # 随机休眠3-5秒
    time.sleep(random.randint(3, 5))
	
    
'''
消费者,负责访问URL
'''

import redis
import random
import time

r = redis.Redis(host="127.0.0.1", port=6379, db=0)

while True:
    # 从列表中获取URL,结果为元组,或者None
    url = r.brpop("spider:urls", 6) # 设置阻塞,没有URL的时候阻塞,3秒另作处理
    if url:
        print(url[1].decode())
        print("正在抓取......")
    else:
        print("抓取结束")
        break

4. 操作散列

4.1 基本方法

# 1、更新一条数据的属性,没有则新建
hset(name, key, value)
# 2、读取这条数据的指定属性,返回字符串类型
hget(name, key)
# 3、批量更新数据(没有则新建)属性 hmset(name, {key1:value1, key2:value2})
hmset(name, mapping)
# 4、批量读取数据(没有则新建)属性
hmget(name, keys, *args)
# 5、获取这条数据的所有属性和对应的值,返回字典类型
hgetall(name)
# 6、获取这条数的所有属性名,返回列表
hkeys(name)
# 7、删除这条数据的指定属性
hdel(name, *keys)

4.1 应用场景

微博好友

1、用户ID,field为好友ID,value为关注时间

2、用户维度统计(关注数、粉丝数、喜欢商品数、发帖数)

组合使用

redis+mysql+hash组合使用

  • 原理

用户想要查询个人信息

1、到redis缓存中查询个人信息

2、redis中查不到数据就到mysql查,并缓存到redis

3、再次查询个人信息

  • 代码实现

    -- mysql建表
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for user
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user`  (
      `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `password` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `gender` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `age` tinyint(4) NULL DEFAULT NULL
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES ('Chancey', '123', '男', 33);
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    
    '''
    python文件
    1、到redis缓存中查询个人信息
    2、redis中查不到数据就到mysql查,并缓存到redis
    3、再次查询个人信息
    '''
    
    import redis
    import pymysql
    
    # 用户从终端输入要查询的用户:chancey
    username = input("请输入用户名:")
    
    # 从redis中查询
    r = redis.Redis(host="127.0.0.1", port=6379, db=0)
    result = r.hgetall(username)
    
    # 查到则打印
    if result :
            print("Redis数据:", result)
    
    # 查不到则进mysql查
    else:
        db = pymysql.connect("localhost", "root", "Asd.1234", "userdb", charset="utf8mb4")
    
        cursor = db.cursor()
        sel = "select gender,age from user where username=%s"
        cursor.execute(sel, [username])
        res = cursor.fetchall()
        if not res:
            print("MySQL中无此用户")
        else:
            print("MySQL数据:", res)
            # 添加到redis,设置过期时间为5分钟
            r.hmset(username, {"gender":res[0][0], "age":res[0][1]})
            r.expire(username, 20)
    

5. 操作集合

5.1 基本方法

# 1、给name对应的集合中添加元素
r.sadd(name, values)
r.sadd("set_name", "Tom")
r.sadd("set_name", "Tom", "Jim")

# 2、获取name对应的集合的所有成员
r.smembers(name)

# 3、获取name对应的集合中的元素
r.scard(name)

# 4、检查vlaue是否是name对应的集合中元素
sismember(name, value)

# 5、随机删除并返回指定集合的一个元素
spop(name)

# 6、删除集合中的某个元素
srem(name, value)

# 7、获取多个name对应集合的交集
sinter(keys, *args)

# 8、获取多个name对应的集合的并集
sunion(keys, *args)

5.2 应用场景

sina的共同关注

需求:当用户访问另一个用户的时候,会显示出两个用户共同关注过哪些相同的用户

设计:将每一个用户关注的用户放在集合,求交集即可

# user_one 关注的人
r.sadd("user_one", "user001", "user002", "user003", "user004")
# user_two 关注的人
r.sadd("user_two", "user002", "user003", "user004", "user005")
# user_one 和 user_two 共同关注的人
r.sinterstore("user_all", "user_one", "user_two")
for i in r.smembers("user_all"):
    print(i.decode())

6. 操作有序集合

网易云音乐排行榜

1、每首歌的革命作为元素(不考虑重复)

2、每首歌的播放次数作为分值

3、使用zrevrange来获取播放次数最多的歌曲

import redis

r = redis.Redis(host="127.0.0.1", port=6379, db=0)

r.zadd("ranking", {"song1":1, "song2":1, "song3":1, "song4":1})
r.zadd("ranking", {"song5":1, "song6":1, "song7":1})
r.zadd("ranking", {"song8":1, "song9":1})

# 给任意三个元素增加任意分值
# zincrby ranking increment member
r.zincrby("ranking", 50, "song3")
r.zincrby("ranking", 80, "song5")
r.zincrby("ranking", 90, "song8")

# 获取排行榜前三名
result = r.zrevrange("ranking", 0, 2, withscores=True)

i = 1
for r in result:
    print("第{}名:{} 播放量:{}".format(i, r[0].decode(), int(r[1])))
    i += 1

手机销售

1、第一天 zadd mobile-001 5000 "huawei" 4000 "oppo" 3000 "iphone"

​ 第二天zadd mobile-002 5200 "huawei" 4300 "oppo" 3230 "iphone"

​ 第四天zadd mobile-003 5500 "huawei" 4660 "oppo" 3580 "iphone"

import redis

r = redis.Redis(host="127.0.0.1", port=6379, db=0)

r.zadd("ranking", {"song1":1, "song2":1, "song3":1, "song4":1})
r.zadd("ranking", {"song5":1, "song6":1, "song7":1})
r.zadd("ranking", {"song8":1, "song9":1})

# 给任意三个元素增加任意分值
# zincrby ranking increment member
r.zincrby("ranking", 50, "song3")
r.zincrby("ranking", 80, "song5")
r.zincrby("ranking", 90, "song8")

# 获取排行榜前三名
result = r.zrevrange("ranking", 0, 2, withscores=True)

i = 1
for r in result:
    print("第{}名:{} 播放量:{}".format(i, r[0].decode(), int(r[1])))
    i += 1

# 第一名: 海阔天空  播放量6666
# 第二名
# 第三名

#[(元素,分值), (), (), ()]
# result = r.zrange("ranking", 0, -1, withscores=True)

2、获取三款手机的销量排名

# 命令行实现
zunionstore mobile-001:003 mobile-001 mobile-002 mobile-003 aggregate max
zrevrange mobile-001:003 0 -1 withscores

# python 实现
import redis

r = redis.Redis(host="127.0.0.1", port=6379, db=0)

# 第一天
day01_dict = {"huawei":5000, "oppo":"4000", "iphone":3000}
day02_dict = {"huawei":5200, "oppo":"4300", "iphone":3230}
day03_dict = {"huawei":5500, "oppo":"4660", "iphone":3580}

r.zadd("mobile-day01", day01_dict)
r.zadd("mobile-day02", day02_dict)
r.zadd("mobile-day03", day03_dict)

r.zunionstore("mobile-day01:03", ("mobile-day01", "mobile-day02", "mobile-day03"), aggregate="max")
rlist = r.zrevrange("mobile-day01:03", 0, -1, withscores=True)

i = 1
for r in rlist:
    print("第{}名:{}".format(i, r[0].decode()))
    i += 1
posted @ 2019-09-02 20:02  ChanceySolo  阅读(269)  评论(0编辑  收藏  举报