Python 操作 Redis¶
Author: 史川诚
学习前建议¶
先学习一下redis的入门,了解redis的配置和部分语法。
安装redis库¶
链接redis数据库¶
第一种简单的链接方式
连接池连接方式
import redis
redis_pool = redis.ConnectionPool(host='127.0.0.1', port= 6379, password= 'your pw', db= 0)
redis_db = redis.Redis(connection_pool= redis_pool)
String¶
获取一个键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.get("name")
print(res)
写入一个简单的键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.set("name", "Shichuanchneg")
写入多个键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.mset({"name:100":"scc", "name:101":"lxl"})
获取多个键值对数据¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.mget("name:100", "name:101")
先获取再写入一个键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.getset("name", "shhh")
print(res)
查看是否存在,而后设置键值对¶
先查看是否存在键值对,若不存在直接创建,若存在不进行操作.若已存在返回False.
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.setnx("name")
print(res)
写入多个键值对,优先判断是否原有存在在¶
这是一个原子性操作,当其中一个失败了,另一个也不干了
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.msetnx({"name":"scc", "age1":10})
print(res)
延长字符串键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.append("name", "abc")
返回字符串长度¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.strlen("nmae")
print(res)
获取一个范围内的字符串¶
当数据范围为0和-1时,默认传输全部的字符串
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.getrange("name", 0, -1)
print(res)
res = redis_db.getrange("name", 0, 2)
print(res)
修正一定范围内的字符串¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.setrange("name", 1, "cccc")
数据增长1 (文章观看量,视频播放量,网页点击量)¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.set("age", 10)
redis_db.incr("age")
数据降低1 (文章观看量,视频播放量,网页点击量)¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.set("age", 10)
redis_db.decr("age")
数据增长一定的步长¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.set("age", 10)
redis_db.incrby("age", 10)
数据降低一定的步长¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.set("age", 10)
redis_db.decrby("age", 10)
样例代码 文章阅读数问题¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.mset({"page:1:title":"page1",
"page:1:author":"scc",
"page:1:views":100
})
redis_db.mset({"page:2:title":"page2",
"page:2:author":"scc",
"page:2:views":100
})
redis_db.mset({"page:3:title":"page3",
"page:3:author":"scc",
"page:3:views":100
})
while True:
res = int(input("请输入您想看的文章"))
if res == 1:
redis_db.incr("page:1:views")
elif res == 2:
redis_db.incr("page:2:views")
elif res == 3:
redis_db.incr("page:3:views")
else:
print("输入错误,下次见")
break
List¶
列表左侧插入数据¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.lpush("score", 90, 100, 85, 78)
列表右侧插入数据¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.rpush("score", 10, 40, 50)
当key存在时再左侧插入¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.lpushx("score1", 10, 100)
print(res)
当key存在时再右侧插入¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.rpushx("score1", 10, 100)
print(res)
计算list元素个数¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.llen("score")
print(res)
左侧删除一个元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.lpop("score")
右侧删除一个元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.rpop("score")
向指定一个元素前后插入一个元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.linsert("score", "BEFORE", 10, "100")
redis_db.linsert("score", "AFTER", 10, "helloworle")
对一个指定的索引位置的元素进行修改赋值¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.lset("score", 2, 100)
print(res)
通过索引获取数值¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.lindex("score", 2)
print(res)
查看摸一个范围内的list的数值¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.lrange("score", 0, -1)
print(res)
res = redis_db.lrange("score", 0, 20)
print(res)
删除一个指定的元素value,指定的个数个¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.lrem("score", 2, 80)
将list中右侧删除一个元素,并放到目标list的左侧¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.rpoplpush("score", "score")
将List进行修剪,保留一定范围的list数据¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.ltrim("score", 0, 10)
将某一个数据的索引返回¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.lpos("score", 100)
print(res)
Hash¶
哈希中添加一个键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.hset("myhash", "user0001", "shichuanchneg")
哈希中批量添加键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.hset("myhash", mapping={"user0003":"lixinlong", "user0004":"qiuyuchen"})
哈希中获取一个键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.hget("myhash", "user0001")
print(res)
哈希中批量获取键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.hmget("myhash", "user0001", "user0002")
print(res)
res = redis_db.hmget("myhash", ["user0001", "user0002"])
print(res)
获取哈希中全部键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.hgetall("myhash")
print(res)
获取哈希中所有的键值对个数¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.hlen("myhash")
print(res)
获取哈希中的所有键¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.hkeys("myhash")
print(res)
获取哈希中所有的数值¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.hvals("myhash")
print(res)
确定某一个键在哈希中是否存在¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.hexists("myhash", "user")
print(res)
删除哈希中的某一个键值对¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.hdel("myhash", "user0001")
自增哈希中的数值,步长可以为负数(变相降低)¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.hset("myhash", "user0001age", 10)
redis_db.hincrby("myhash", "user0001age", -1)
Set¶
向集合中添加元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.sadd("myset", 100, 40, 200, 1000)
获取集合中的元素个数¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.scard("myset")
print(res)
获取两个集合之间的不同元素¶
当参数先后顺序不同时,会产生不同的结果。这个可以自行理解一下,很简单。
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.sadd("myset2", 90, 40, 200, 2000)
res = redis_db.sdiff("myset", "myset2")
print(res)
res = redis_db.sdiff("myset2", "myset")
print(res)
获取两个集合之间的交集¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.sinter("myset", "myset2")
print(res)
获取两个集合之间的并集¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.sunion("myset", "myset2")
print(res)
获取一个集合中的元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.smembers("myset")
print(res)
用于确定摸一个元素是否在一个集合中¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.sismember("myset", 100000000)
print(res)
res = redis_db.sismember("myset", 1000)
print(res)
从集合中删除一个指定的元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.srem("myset", 1000)
从集合中随机删除指定个数个元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.spop("myset2", 4)
从集合中随机获取指定个数个元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.srandmember("myset", 3)
print(res)
将一个元素从一个集合移动到另一个集合中¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.smove("myset2", "myset", 40)
Sorted Set¶
插入一个或者多个元素进入到有序集合中¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.zadd('myzset', {"scc":1000, "ljy":2000, "lxl":3000})
获取有序集合的元素总数¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.zcard("myzset")
print(res)
获取有序集合中分数 在 [min,max] 之间的个数¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.zcount("myzset", 0, 2000)
print(res)
根据索引显示一定范围内的数据¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.zrange("myzset", 1, 3, withscores=True)
print(res)
res = redis_db.zrange("myzset", 0, -1, withscores=True)
print(res)
根据分数显示一定范围内的数据¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.zrangebyscore("myzset", 0, 2000)
print(res)
根据member删除数据¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.zrem("myzset", "scc")
根据排行的范围进行删除¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.zadd("myzset", {"scc":1000,"qyc":2500,"ldy":2600,"hzn":2700})
redis_db.zremrangebyrank("myzset", 0, 1)
根据分数范围删除元素¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.zremrangebyscore("myzset", 1000, 1500)
获取某一个member的排行¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
res = redis_db.zrank("myzset", "qyc")
print(res)
某一个member的数值进行自增或者自减¶
import redis
redis_db = redis.Redis(host="127.0.0.1", password="your pwd", port=6379, db=0)
redis_db.zincrby("myzset", 10, "scc")
redis_db.zincrby("myzset", -10, "qyc")
Redis的SDS字符串类型¶
什么是SDS字符串类型¶
首先SDS字符串类型就是Simple Dynamic String
,也就是简单动态字符串。他的根源就是通过C语言来实现的。我将源码中的代码进行一个简化。可以看到这样一个结构体。
struct sdshdr {
// 记录 buf 数组中已使用字节的数量
// 等于 SDS 所保存字符串的长度
int len;
// 记录 buf 数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
};
free
属性的值为 0 ,表示这个 SDS 没有分配任何未使用空间。
len
属性的值为 5 ,表示这个 SDS 保存了一个五字节长的字符串。
buf
属性是一个char
类型的数组,那么当我们要存储一个redis的时候,那么buf中就会存储五个字节的位置,以及最后的\0。
SDS 遵循 C 字符串以空字符结尾的惯例,保存空字符的 1 字节空间不计算在 SDS 的 len 属性里面,并且为空字符分配额外的 1 字节空间,以及添加空字符到字符串末尾等操作都是由 SDS 函数自动完成的,所以这个空字符对于 SDS 的使用者来说是完全透明的。
遵循空字符结尾这一惯例的好处是,SDS 可以直接重用一部分 C 字符串函数库里面的函数。
举个例子,如果我们有一个指向SDS的指针 s
,那么我们可以直接使用 stdio.h/printf
函数,通过执行以下语句:
SDS与C语言的字符串类型的区别¶
根据传统,C
语言使用长度为N+1
的字符数组来表示长度为N
的字符串,并且字符数组的最后一个元素总是空字符'\0'
。C语言使用的这种简单的字符串表示方式,并不能满足Redis对字符串在安全性、效率、以及功能方面的要求。