https://github.com/QInzhengk/Math-Model-and-Machine-Learning
@[TOC](Python redis 使用(源码))
Python redis 使用介绍(通过源码查看怎么用)
redis 是一个 Key-Value 数据库,Value 支持 string(字符串),list(列表),set(集合),zset(有序集合),hash(哈希类型)等类型。
1、安装启动 redis
1.1 用brew安装
1.查看系统是否已经安装了Redis
这个命令会展示此系统下的redis信息,如果没有安装,会展示not install
2.输入命令安装Redis
可能需要等一会,系统下载完redis的包,会自动进行安装
3.启动redis
1
| brew services start redis
|
这个命令会在后台启动redis服务,并且每一次登录系统,都会自动重启
如果你不想/不需要后台服务,你可以运行:
1
| /usr/local/opt/redis/bin/redis-server /usr/local/etc/redis.conf
|
4.查看redis服务进程
可以通过下面命令查看redis是否正在运行
默认端口号为 6379,ctrl+D 退出
这个命令会读取redis的配置文件,并且在redis运行的过程中也会看到实时的日志打印。
2、redis 模块(Python)
redis 提供两个类 Redis 和 StrictRedis
- StrictRedis 用于实现大部分官方的命令
- Redis 是 StrictRedis 的子类,用于向后兼用旧版本。
redis 取出的结果默认是字节,可以设定 decode_responses=True 改成字符串。
2.1 连接池
redis-py 使用 connection pool 来管理对一个 redis server 的所有连接,避免每次建立、释放连接的开销。
默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数 Redis,这样就可以实现多个 Redis 实例共享一个连接池。
3、redis 基本命令 String
1
| set(name, value, ex=None, px=None, nx=False, xx=False)
|
在 Redis 中设置值,默认,不存在则创建,存在则修改。
参数:
- ex - 过期时间(秒)
- px - 过期时间(毫秒)
- nx - 如果设置为True,则只有name不存在时,当前set操作才执行
- xx - 如果设置为True,则只有name存在时,当前set操作才执行
1.setnx(name, value) 设置值,只有name不存在时,执行设置操作(添加)
2.setex(name, time, value) 设置值
- time - 过期时间(数字秒 或 timedelta对象)
1 2 3 4 5 6 7 8 9 10 11
| import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.setex("fruit2", 5, "orange") print(r.get('fruit2')) time.sleep(5) print(r.get('fruit2'))
orange None
|
3.psetex(name, time_ms, value) 设置值
- time_ms - 过期时间(数字毫秒 或 timedelta对象)
4.mset(self, mapping) 批量设置值
1 2 3 4 5 6
| r.mset({'k1': 'v1', 'k2': 'v2'}) print(r.mget("k1", "k2")) print(r.mget("k1"))
['v1', 'v2'] ['v1']
|
5.mget(keys, *args) 批量获取
1 2 3 4 5 6 7
| print(r.mget('k1', 'k2')) print(r.mget(['k1', 'k2'])) print(r.mget("fruit", "fruit1", "fruit2", "k1", "k2"))
['v1', 'v2'] ['v1', 'v2'] ['watermelon', None, 'orange', 'v1', 'v2']
|
6.getset(name, value) 设置新值并获取原来的值
1
| print(r.getset("food", "barbecue"))
|
7.getrange(key, start, end) 获取子序列(根据字节获取,非字符)
- start - 起始位置(字节)
- end - 结束位置(字节)
1 2 3 4 5 6
| r.set("cn_name", "君惜大大") print(r.getrange("cn_name", 0, 2)) print(r.getrange("cn_name", 0, -1)) r.set("en_name","junxi") print(r.getrange("en_name", 0, 2)) print(r.getrange("en_name", 0, -1))
|
8.setrange(name, offset, value) 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
- offset - 字符串的索引,字节(一个汉字三个字节)
- value - 要设置的值
1 2
| r.setrange("en_name", 1, "ccc") print(r.get("en_name"))
|
9.strlen(name) 返回name对应值的字节长度(一个汉字3个字节)
10.incr(self, name, amount=1) 自增 name 对应的值,当 name 不存在时,则创建 name=amount,否则,则自增。
- name - Redis的name
- amount - 自增数(必须是整数)
注:同 incrby
1 2 3 4
| r.set("foo", 123) print(r.mget("foo", "foo1", "foo2", "k1", "k2")) r.incr("foo", amount=1) print(r.mget("foo", "foo1", "foo2", "k1", "k2"))
|
应用场景 – 页面点击数
假定对一系列页面需要记录点击次数。例如论坛的每个帖子都要记录点击次数,而点击次数比回帖的次数的多得多。如果使用关系数据库来存储点击,可能存在大量的行级锁争用。所以,点击数的增加使用redis的INCR命令最好不过了。
当redis服务器启动时,可以从关系数据库读入点击数的初始值(12306这个页面被访问了34634次)
1 2
| r.set("visit:12306:totals", 34634) print(r.get("visit:12306:totals"))
|
每当有一个页面点击,则使用INCR增加点击数即可。
1 2
| r.incr("visit:12306:totals") r.incr("visit:12306:totals")
|
页面载入的时候则可直接获取这个值
1
| print(r.get("visit:12306:totals"))
|
11.decr(self, name, amount=1) 自减 name 对应的值,当 name 不存在时,则创建 name=amount,否则,则自减。
- name - Redis的name
- amount - 自减数(整数)
注:同 decrby
1 2 3 4 5
| r.decr("foo4", amount=3) r.decr("foo1", amount=1) print(r.mget("foo1", "foo4"))
['124', '-3']
|
12.append(key, value) 在redis name对应的值后面追加内容
- key - redis的name
- value - 要追加的字符串
1 2
| r.append("name", "haha") print(r.mget("name"))
|
4、redis 基本命令 hash
1、单个增加–修改(单个取出)–没有就新增,有的话就修改
1
| hset(name, key, value, mapping=None)
|
name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
- name - redis的name
- key - name对应的hash中的key
- value - name对应的hash中的value
- mapping - 接受一个由键/值对组成的字典
注:hsetnx(name, key, value) 当name对应的hash中不存在当前key时则创建(相当于添加)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.hset("hash1", "k1", "v1") r.hset("hash1", "k2", "v2") print(r.hkeys("hash1")) print(r.hget("hash1", "k1")) print(r.hmget("hash1", "k1", "k2")) print(r.hsetnx("hash1", "k2", "v3")) print(r.hget("hash1", "k2"))
['k1', 'k2'] v1 ['v1', 'v2'] 0 v2
|
2、批量增加(取出)
在name对应的hash中批量设置键值对
- name - redis的name
- mapping - 字典
1
| r.hmset("hash2", {"k2": "v2", "k3": "v3"})
|
在name对应的hash中获取根据key获取value
1
| hmget(name, keys, *args)
|
在name对应的hash中获取多个key的值
- name - reids对应的name
- keys - 要获取key集合,如:[‘k1’, ‘k2’, ‘k3’]
- *args - 要获取的key,如:k1,k2,k3
1 2 3
| print(r.hget("hash2", "k2")) print(r.hmget("hash2", "k2", "k3")) print(r.hmget("hash2", ["k2", "k3"]))
|
3、取出所有的键值对
获取name对应hash的所有键值
1 2 3
| print(r.hgetall("hash1"))
{'k1': 'v1', 'k2': 'v2'}
|
4、得到所有键值对的格式 hash长度
获取name对应的hash中键值对的个数
5、得到所有的keys(类似字典的取所有keys)
获取name对应的hash中所有的key的值
6、得到所有的value(类似字典的取所有value)
获取name对应的hash中所有的value的值
7、判断成员是否存在(类似字典的in)
检查 name 对应的 hash 是否存在当前传入的 key
1 2
| print(r.hexists("hash1", "k4")) print(r.hexists("hash1", "k1"))
|
8、删除键值对
将name对应的hash中指定key的键值对删除
1 2 3 4 5
| print(r.hgetall("hash1")) r.hset("hash1", "k2", "v222") r.hset("hash1", "k11", "v1") r.hdel("hash1", "k1") print(r.hgetall("hash1"))
|
9、自增自减整数(将key对应的value–整数 自增1或者2,或者别的整数 负数就是自减)
1
| hincrby(name, key, amount=1)
|
自增name对应的hash中的指定key的值,不存在则创建key=amount
参数:
- name - redis中的name
- key - hash对应的key
- amount - 自增数(整数)
1 2 3 4 5
| r.hset("hash1", "k3", 123) r.hincrby("hash1", "k3", amount=-1) print(r.hgetall("hash1")) r.hincrby("hash1", "k4", amount=1) print(r.hgetall("hash1"))
|
10、自增自减浮点数(将key对应的value–浮点数 自增1.0或者2.0,或者别的浮点数 负数就是自减)
1
| hincrbyfloat(name, key, amount=1.0)
|
自增name对应的hash中的指定key的值,不存在则创建key=amount
参数:
- name - redis中的name
- key - hash对应的key
- amount,自增数(浮点数)
自增 name 对应的 hash 中的指定 key 的值,不存在则创建 key=amount。
1 2 3 4 5 6 7 8
| r.hset("hash1", "k5", "1.0") r.hincrbyfloat("hash1", "k5", amount=-1.5) print(r.hgetall("hash1")) r.hincrbyfloat("hash1", "k6", amount=-1.0) print(r.hgetall("hash1"))
{'k2': 'v222', 'k11': 'v1', 'k3': '123', 'k4': '1', 'k5': '-0.5', 'k6': '-1'} {'k2': 'v222', 'k11': 'v1', 'k3': '123', 'k4': '1', 'k5': '-0.5', 'k6': '-2'}
|
11、取值查看–分片读取
1
| hscan(name, cursor=0, match=None, count=None)
|
增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而防止内存被撑爆
- name - redis的name
- cursor - 游标(基于游标分批取获取数据)
- match - 匹配指定key,默认None 表示所有的key
- count - 每次分片最少获取个数,默认None表示采用Redis的默认分片个数
1 2 3 4 5 6 7 8
| 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None) 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None) ... 直到返回值cursor的值为0时,表示数据已经通过分片获取完毕
print(r.hscan("hash1"))
(0, {'k2': 'v222', 'k11': 'v1', 'k3': '123', 'k4': '1', 'k5': '-0.5', 'k6': '-5'})
|
12、hscan_iter(name, match=None, count=None)
利用yield封装hscan创建生成器,实现分批去redis中获取数据
- match - 匹配指定key,默认None 表示所有的key
- count - 每次分片最少获取个数,默认None表示采用Redis的默认分片个数
1 2 3 4 5 6 7 8 9 10 11
| for item in r.hscan_iter('hash1'): print(item) print(r.hscan_iter("hash1"))
('k2', 'v222') ('k11', 'v1') ('k3', '123') ('k4', '1') ('k5', '-0.5') ('k6', '-6') <generator object ScanCommands.hscan_iter at 0x7f94486cc270>
|
5、redis基本命令 list
1.增加(类似于list的append,只是这里是从左边新增加)–没有就新建
在name对应的list中添加元素,每个新的元素都添加到列表的最左边
1 2 3 4 5 6 7
| import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.lpush("list1", 11, 22, 33) print(r.lrange('list1', 0, -1)) 保存顺序为: 33,22,11
|
rpush:增加(从右边增加)–没有就新建
1 2 3
| r.rpush("list2", 44, 55, 66) print(r.llen("list2")) print(r.lrange("list2", 0, -1))
|
2.往已经有的name的列表的左边添加元素,没有的话无法创建
在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
1 2 3 4 5 6
| r.lpushx("list10", 10) print(r.llen("list10")) print(r.lrange("list10", 0, -1)) r.lpushx("list2", 77) print(r.llen("list2")) print(r.lrange("list2", 0, -1))
|
rpushx:往已经有的name的列表的右边添加元素,没有的话无法创建
1 2 3
| r.rpushx("list2", 99) print(r.llen("list2")) print(r.lrange("list2", 0, -1))
|
3.新增(固定索引号位置插入元素)
1
| linsert(name, where, refvalue, value))
|
在name对应的列表的某一个值前或后插入一个新值
- name - redis的name
- where - before/after
- refvalue - 标杆值,即:在它前后插入数据
- value - 要插入的数据
1 2
| r.linsert("list2", "before", "11", "00") print(r.lrange("list2", 0, -1))
|
4.修改(指定索引号进行修改)
1
| r.lset(name, index, value)
|
对name对应的list中的某一个索引位置重新赋值
- name - redis的name
- index - list的索引位置
- value - 要设置的值
1 2
| r.lset("list2", 0, -11) print(r.lrange("list2", 0, -1))
|
5.删除(指定值进行删除)
1
| r.lrem(name, count, value)
|
在name对应的list中删除指定的值
- name - redis的name
- count
- count=0,删除列表中所有的指定值;
- count=1,从前到后,删除左边第1个
- count=-2,从后向前,删除2个
- value - 要删除的值
1 2 3 4 5 6
| r.lrem("list2", 1, "11") print(r.lrange("list2", 0, -1)) r.lrem("list2", -1, "99") print(r.lrange("list2", 0, -1)) r.lrem("list2", 0, "22") print(r.lrange("list2", 0, -1))
|
6.删除并返回
在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
1 2 3 4
| r.lpop("list2") print(r.lrange("list2", 0, -1)) print(r.rpop("list2")) print(r.lrange("list2", 0, -1))
|
7.删除索引之外的值
在name对应的列表中移除没有在start-end索引之间的值
- name - redis的name
- start - 索引的起始位置
- end - 索引结束位置
1 2
| r.ltrim("list2", 0, 2) print(r.lrange("list2", 0, -1))
|
8.取值(根据索引号取值)
在name对应的列表中根据索引获取列表元素
1 2 3 4 5
| print(r.lindex("list2", 0)) print(type(r.lindex("list2", 0)))
00 <class 'str'>
|
9.移动 元素从一个列表移动到另外一个列表
从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
- src - 要取数据的列表的 name
- dst - 要添加数据的列表的 name
1 2
| r.rpoplpush("list1", "list2") print(r.lrange("list2", 0, -1))
|
10.移动 元素从一个列表移动到另外一个列表 可以设置超时
1
| brpoplpush(src, dst, timeout=0)
|
从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
- src - 取出并要移除元素的列表对应的name
- dst - 要插入元素的列表对应的name
- timeout - 当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞
1 2
| r.brpoplpush("list1", "list2", timeout=2) print(r.lrange("list2", 0, -1))
|
11.一次移除多个列表
将多个列表排列,按照从左到右去pop对应列表的元素
- keys - redis的name的集合
- timeout - 超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
r.brpop(keys, timeout) 同 blpop,将多个列表排列,按照从右像左去移除各个列表内的元素
1 2 3 4 5
| r.lpush("list10", 3, 4, 5) r.lpush("list11", 3, 4, 5) while True: r.blpop(["list10", "list11"], timeout=2) print(r.lrange("list10", 0, -1), r.lrange("list11", 0, -1))
|
12.自定义增量迭代
由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要获取name对应的所有列表。
循环列表
但是,如果列表非常大,那么就有可能在第一步时就将程序的内容撑爆,所以有必要自定义一个增量迭代的功能:
1 2 3 4 5 6 7 8 9 10 11 12 13
| def list_iter(name): """ 自定义redis列表增量迭代 :param name: redis中的name,即:迭代name对应的列表 :return: yield 返回 列表元素 """ list_count = r.llen(name) for index in range(list_count): yield r.lindex(name, index)
for item in list_iter('list2'): print(item)
|
6、redis基本命令 set
1.新增
1 2 3 4 5 6
| r.sadd("set1", 33, 44, 55, 66) print(r.scard("set1")) print(r.smembers("set1"))
4 {'66', '55', '33', '44'}
|
2.获取元素个数 类似于len
获取name对应的集合中元素个数
3.获取集合中所有的成员
获取name对应的集合的所有成员
获取集合中所有的成员–元组形式
1
| sscan(name, cursor=0, match=None, count=None)
|
1 2 3
| print(r.sscan("set1"))
(0, ['33', '44', '55', '66'])
|
获取集合中所有的成员–迭代器的方式
1
| sscan_iter(name, match=None, count=None)
|
同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
1 2 3 4 5 6 7
| for i in r.sscan_iter("set1"): print(i)
33 44 55 66
|
4.差集
在第一个name对应的集合中且不在其他name对应的集合的元素集合
1 2 3 4 5
| r.sadd("set2", 11, 22, 33) print(r.smembers("set1")) print(r.smembers("set2")) print(r.sdiff("set1", "set2")) print(r.sdiff("set2", "set1"))
|
差集–差集存在一个新的集合中
1
| sdiffstore(dest, keys, *args)
|
获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中,返回值为新集合中键的数目。
1 2 3 4 5
| print(r.sdiffstore("set3", "set1", "set2")) print(r.smembers("set3"))
3 {'66', '44', '55'}
|
5.交集
获取多一个name对应集合的交集
1
| print(r.sinter("set1", "set2"))
|
交集–交集存在一个新的集合中,返回值为新集合中键的数目。
1
| sinterstore(dest, keys, *args)
|
获取多一个name对应集合的并集,再将其加入到dest对应的集合中
1 2 3 4 5
| print(r.sinterstore("set3", "set1", "set2")) print(r.smembers("set3"))
6 {'55', '33', '22', '44', '66', '11'}
|
6.并集
获取多个name对应的集合的并集,返回值为新集合中键的数目。
1 2 3
| print(r.sunion("set1", "set2"))
{'44', '66', '55', '33', '22', '11'}
|
并集–并集存在一个新的集合
1
| sunionstore(dest,keys, *args)
|
获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中
1 2 3 4 5
| print(r.sunionstore("set3", "set1", "set2")) print(r.smembers("set3"))
3 {'55', '66', '44'}
|
8.判断是否是集合的成员 类似in
检查value是否是name对应的集合的成员,结果为True和False
1 2
| print(r.sismember("set1", 33)) print(r.sismember("set1", 23))
|
9.移动
将某个成员从一个集合中移动到另外一个集合
1 2 3 4 5 6
| r.smove("set1", "set2", 44) print(r.smembers("set1")) print(r.smembers("set2"))
{'55', '33', '66'} {'11', '33', '44', '22'}
|
10.删除–随机删除并且返回被删除值
从集合移除一个成员,并将其返回,说明一下,集合是无序的,所有是随机删除的
1 2
| print(r.spop("set2")) print(r.smembers("set2"))
|
11.删除–指定值删除
在name对应的集合中删除某些值
1 2
| print(r.srem("set2", 11)) print(r.smembers("set2"))
|
7、redis基本命令 有序set
Set操作,Set集合就是不允许重复的列表,本身是无序的。
有序集合,在集合的基础上,为每个元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
1.新增
1
| zadd(name, mapping, nx=False, xx=False, ch=False, incr=False, gt=None, lt=None)
|
在name对应的有序集合中添加元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.zadd("zset1", {"n1": 11, "n2": 22}) r.zadd("zset2", {'m1': 22, 'm2': 44}) print(r.zcard("zset1")) print(r.zcard("zset2")) print(r.zrange("zset1", 0, -1)) print(r.zrange("zset2", 0, -1, withscores=True))
2 2 ['n1', 'n2'] [('m1', 22.0), ('m2', 44.0)]
|
2.获取有序集合元素个数 类似于len
获取name对应的有序集合元素的数量
3.获取有序集合的所有元素
1
| r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
|
按照索引范围获取name对应的有序集合的元素
- name - redis的name
- start - 有序集合索引起始位置(非分数)
- end - 有序集合索引结束位置(非分数)
- desc - 排序规则,默认按照分数从小到大排序
- withscores - 是否获取元素的分数,默认只获取元素的值
- score_cast_func - 对分数进行数据转换的函数
3-1 从大到小排序(同zrange,集合是从大到小排序的)
1
| zrevrange(name, start, end, withscores=False, score_cast_func=float)
|
1 2
| print(r.zrevrange("zset1", 0, -1)) print(r.zrevrange("zset1", 0, -1, withscores=True))
|
3-2 按照分数范围获取name对应的有序集合的元素
1
| zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
|
1 2 3 4 5 6 7 8
| for i in range(1, 30): element = 'n' + str(i) r.zadd("zset3", {element: i}) print(r.zrangebyscore("zset3", 15, 25)) print(r.zrangebyscore("zset3", 12, 22, withscores=True))
['n15', 'n16', 'n17', 'n18', 'n19', 'n20', 'n21', 'n22', 'n23', 'n24', 'n25'] [('n12', 12.0), ('n13', 13.0), ('n14', 14.0), ('n15', 15.0), ('n16', 16.0), ('n17', 17.0), ('n18', 18.0), ('n19', 19.0), ('n20', 20.0), ('n21', 21.0), ('n22', 22.0)]
|
3-3 按照分数范围获取有序集合的元素并排序(默认从大到小排序)
1
| zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
|
1
| print(r.zrevrangebyscore("zset3", 22, 11, withscores=True))
|
3-4 获取所有元素–默认按照分数顺序排序
1
| zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
|
1 2 3
| print(r.zscan("zset3"))
(0, [('n1', 1.0), ('n2', 2.0), ('n3', 3.0), ('n4', 4.0), ('n5', 5.0), ('n6', 6.0), ('n7', 7.0), ('n8', 8.0), ('n9', 9.0), ('n10', 10.0), ('n11', 11.0), ('n12', 12.0), ('n13', 13.0), ('n14', 14.0), ('n15', 15.0), ('n16', 16.0), ('n17', 17.0), ('n18', 18.0), ('n19', 19.0), ('n20', 20.0), ('n21', 21.0), ('n22', 22.0), ('n23', 23.0), ('n24', 24.0), ('n25', 25.0), ('n26', 26.0), ('n27', 27.0), ('n28', 28.0), ('n29', 29.0)])
|
3-5 获取所有元素–迭代器
1
| zscan_iter(name, match=None, count=None,score_cast_func=float)
|
1 2
| for i in r.zscan_iter("zset3"): print(i)
|
4.zcount(name, min, max)
获取name对应的有序集合中分数 在 [min,max] 之间的个数
1 2
| print(r.zrange("zset3", 0, -1, withscores=True)) print(r.zcount("zset3", 11, 22))
|
5.获取值的索引号
获取某个值在 name对应的有序集合中的索引(从 0 开始)
1
| zrevrank(name, value),从大到小排序。
|
1 2 3 4 5 6 7 8 9
| print(r.zrange("zset3", 0, -1)) print(r.zrank("zset3", "n1")) print(r.zrank("zset3", "n6")) print(r.zrevrank("zset3", "n1"))
['n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11', 'n12', 'n13', 'n14', 'n15', 'n16', 'n17', 'n18', 'n19', 'n20', 'n21', 'n22', 'n23', 'n24', 'n25', 'n26', 'n27', 'n28', 'n29'] 0 5 28
|
6.删除–指定值删除
删除name对应的有序集合中值是values的成员
1 2
| r.zrem("zset3", "n3") print(r.zrange("zset3", 0, -1))
|
7.删除–根据排行范围删除,按照索引号来删除
1
| zremrangebyrank(name, min, max)
|
根据排行范围删除
1 2
| r.zremrangebyrank("zset3", 0, 1) print(r.zrange("zset3", 0, -1))
|
8.删除–根据分数范围删除
1
| zremrangebyscore(name, min, max)
|
根据分数范围删除
1 2
| r.zremrangebyscore("zset3", 11, 22) print(r.zrange("zset3", 0, -1))
|
9.获取值对应的分数
获取name对应有序集合中 value 对应的分数
1
| print(r.zscore("zset3", "n27"))
|
8、其他常用操作
1.删除
根据删除redis中的任意数据类型(string、hash、list、set、有序set)
2.检查名字是否存在
检测redis的name是否存在,存在就是True,False 不存在
1
| print(r.exists("zset1"))
|
3.模糊匹配
根据模型获取redis的name
1 2 3 4
| KEYS * 匹配数据库中所有 key 。 KEYS h?llo 匹配 hello , hallo 和 hxllo 等。 KEYS hllo 匹配 hllo 和 heeeeello 等。 KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
|
4.设置超时时间
为某个redis的某个name设置超时时间
1 2 3 4 5
| r.lpush("list5", 11, 22) r.expire("list5", time=3) print(r.lrange("list5", 0, -1)) time.sleep(3) print(r.lrange("list5", 0, -1))
|
5.重命名
对redis的name重命名
1 2
| r.lpush("list5", 11, 22) r.rename("list5", "list5-1")
|
6.随机获取name
随机获取一个redis的name(不删除)
7.获取类型
获取name对应值的类型
1 2 3 4 5
| print(r.type("set1")) print(r.type("hash2"))
set hash
|
8.查看所有元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| r.scan(cursor=0, match=None, count=None) print(r.hscan("hash2")) print(r.sscan("set3")) print(r.zscan("zset2")) print(r.getrange("foo1", 0, -1)) print(r.lrange("list2", 0, -1)) print(r.smembers("set3")) print(r.zrange("zset3", 0, -1)) print(r.hgetall("hash1"))
(0, {'k2': 'v2', 'k3': 'v3'}) (0, ['44', '55', '66']) (0, [('m1', 22.0), ('m2', 44.0)]) 125.5 ['22', '11', '00'] {'55', '44', '66'} ['n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n23', 'n24', 'n25', 'n26', 'n27', 'n28', 'n29'] {'k2': 'v222', 'k11': 'v1', 'k3': '123', 'k4': '1', 'k5': '-0.5', 'k6': '-6'}
|
9.查看所有元素–迭代器
1 2 3 4 5 6 7 8 9 10
| r.scan_iter(match=None, count=None)
for i in r.hscan_iter("hash1"): print(i)
for i in r.sscan_iter("set3"): print(i)
for i in r.zscan_iter("zset3"): print(i)
|
other 方法
1 2 3 4 5 6
| print(r.get('name')) r.delete("gender") print(r.keys()) print(r.dbsize())
|
管道(pipeline)
redis默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
管道(pipeline)是redis在提供单个请求中缓冲多条服务器命令的基类的子类。它通过减少服务器-客户端之间反复的TCP数据库包,从而大大提高了执行批量命令的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool)
pipe = r.pipeline() pipe.set('name', 'jack') pipe.set('role', 'sb') pipe.sadd('faz', 'baz') pipe.incr('num') pipe.execute() print(r.get("name")) print(r.get("role")) print(r.get("num"))
jack sb 3
|
管道的命令可以写在一起,如:
1 2 3 4
| pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute() print(r.get("name")) print(r.get("role")) print(r.get("num"))
|
参考资料:https://www.runoob.com/w3cnote/python-redis-intro.html