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