Redis简介及Python操作方法

介绍

Redis是一个开源的基于内存也可持久化的Key-Value数据库,采用ANSI C语言编写。它拥有丰富的数据结构,拥有事务功能,保证命令的原子性。由于是内存数据库,读写非常高速,可达10w/s的评率,所以一般应用于数据变化快、实时通讯、缓存等。但内存数据库通常要考虑机器的内存大小。

Redis有16个逻辑数据库(db0-db15),每个逻辑数据库项目是隔离的,默认使用db0数据库。若选择第2个数据库,通过命令 select 2 ,python中连接时可以指定数据库。

常用数据结构

  • String-字符串
  • List-列表
  • Hash-哈希
  • Set-集合
  • ZSet-有序集合
  • Bitmap-位图

python中安装redis模块包

pip install redis

python连接redis

redis 提供两个类 RedisStrictRedis, StrictRedis 用于实现大部分官方的命令,Redis StrictRedis 的子类,用于向后兼用旧版本。
redis 取出的结果默认是字节,我们可以设定 decode_responses=True 改成字符串。

import redis

host = 'localhost' # redis服务地址
port = 6379  # redis服务端口

r = redis.StrictRedis(host=host,port=port,db=0)
key = r.keys()
print(key)

r = redis.StrictRedis(host=host,port=port,db=0,decode_responses=True)
key = r.keys()
print(key)
#[b'proxies:universal']
#['proxies:universal']

连接池

redis-py 使用 connection pool 来管理对一个 redis server 的所有连接,避免每次建立、释放连接的开销。

默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数 Redis,这样就可以实现多个 Redis 实例共享一个连接池。

import redis

host = 'localhost' # redis服务地址
port = 6379  # redis服务端口

pool = redis.ConnectionPool(host=host,port=port,db=0,decode_responses=True)
r = redis.Redis(connection_pool=pool) # 或者用redis.StrictRedis

key = r.keys()
print(key)

#['proxies:universal']

redis基本命令 - string

set(name, value, ex=None, px=None, nx=False, xx=False)

Redis 中设置值,默认,不存在则创建,存在则修改。

参数:

ex - 过期时间(秒)
px - 过期时间(毫秒)
nx - 如果设置为True,则只有name不存在时,当前set操作才执行
xx - 如果设置为True,则只有name存在时,当前set操作才执行
ex - 过期时间(秒) 这里过期时间是3秒,3秒后,键 test 的值就变成None

r.set('test','123456',ex=10)  # 设置键 test的值为123456,过期时间为3秒
print("test的值为:{}".format(r.get('test')))

time.sleep(10)
print("10秒后test的值为:{}".format(r.get('test')))

#test的值为:123456
#10秒后test的值为:None

px - 过期时间(豪秒) 这里过期时间是3豪秒,3毫秒后,键foo的值就变成None

r.set('test','1234',px=3)  # 设置键 test 的值为1234,过期时间为3毫秒
print("test的值为:{}".format(r.get('test')))

time.sleep(0.003)
print("3毫秒后test的值为:{}".format(r.get('test')))

#test的值为:1234
#3毫秒后test的值为:None

nx - 如果设置为True,则只有name不存在时,当前set操作才执行 (新建)

print("当前数据库中存在的键有:{}".format(r.keys()))
print("若test键不存在,则设置test的值为:123456,否则不执行")
r.set('test','123456',nx=True)  # 当test键不存在时,设置键 test 的值为123456
print("test的值为:{}".format(r.get('test')))

#当前数据库中存在的键有:['proxies:universal']
#若test键不存在,则设置test的值为:123456,否则不执行
#test的值为:123456

xx - 如果设置为True,则只有name存在时,当前set操作才执行 (修改)

print("当前数据库中存在的键有:{}".format(r.keys()))
print("若test键存在,则修改test的值为:123456,否则不执行")
r.set('test','123456',xx=True)  # 当test键存在时,修改键 test 的值为123456
print("test的值为:{}".format(r.get('test')))

#当前数据库中存在的键有:['proxies:universal', 'test']
#若test键存在,则修改test的值为:123456,否则不执行
#test的值为:123456

setnx(name, value)

设置值,只有name不存在时,执行设置操作(添加)

setex(name, time, value)

设置值,time - 过期时间(数字秒 或 timedelta对象)

psetex(name, time_ms, value)

设置值,time_ms - 过期时间(数字毫秒 或 timedelta对象)

mset 和 mget

  • mset(*args, **kwargs):批量设置值
  • mget(keys, *args):批量获取值
import redis
import time

host = 'localhost' # redis服务地址
port = 6379  # redis服务端口

pool = redis.ConnectionPool(host=host,port=port,db=0,decode_responses=True)
r = redis.Redis(connection_pool=pool) # 或者用redis.StrictRedis

print("当前数据库中存在的键有:{}".format(r.keys()))

print("设置键 k1和k2的值,分别为v1和v2")
r.mset({'k1': 'v1', 'k2': 'v2'})
print("获取键k1和k2的值")
print(r.mget("k1", "k2"))   # 一次取出多个键对应的值

#当前数据库中存在的键有:['proxies:universal', 'test']
#设置键 k1和k2的值,分别为v1和v2
#获取键k1和k2的值
#['v1', 'v2']

getset(name, value)

设置新值并获取原来的值

import redis
import time

host = '192.168.149.153' # redis服务地址
port = 6379  # redis服务端口

pool = redis.ConnectionPool(host=host,port=port,db=0,decode_responses=True)
r = redis.Redis(connection_pool=pool) # 或者用redis.StrictRedis

print("当前数据库中存在的键有:{}".format(r.keys()))

print("获取键test的值为:{}".format(r.get('test')))

result = r.getset('test','12345')  # 设置键test的新值为12345,并返回原test的值1234
print("键test的原值为:{}".format(result))
print("获取键test的当前的值为:{}".format(r.get('test')))

#当前数据库中存在的键有:['k2', 'proxies:universal', 'test', 'k1']
#获取键test的值为:123456
#键test的原值为:123456
#获取键test的当前的值为:12345

getrange(key, start, end)

获取子序列(根据索引、字节获取)一个汉字占3个字节

参数:

  • start - 起始位置(起始索引从0开始)
  • end - 结束位置
import redis
import time

host = 'localhost' # redis服务地址
port = 6379  # redis服务端口

pool = redis.ConnectionPool(host=host,port=port,db=0,decode_responses=True)
r = redis.Redis(connection_pool=pool) # 或者用redis.StrictRedis

print("当前数据库中存在的键有:{}".format(r.keys()))
print("获取键test的值为:{}".format(r.get('test')))

result = r.getrange('test',0,1)  # 获取索引0到1的子序列
print("键test的0到1的子序列为:{}".format(result))

result = r.getrange('test',1,4)  # 获取索引1到4的子序列
print("键test的1到4的子序列为:{}".format(result))

#当前数据库中存在的键有:['test', 'k2', 'proxies:universal', 'k1']
#获取键test的值为:12345
#键test的0到1的子序列为:12
#键test的1到4的子序列为:2345
import redis
import time

host = 'localhost' # redis服务地址
port = 6379  # redis服务端口

pool = redis.ConnectionPool(host=host,port=port,db=0,decode_responses=True)
r = redis.Redis(connection_pool=pool) # 或者用redis.StrictRedis

print("当前数据库中存在的键有:{}".format(r.keys()))
print("获取键name的值为:{}".format(r.get('name')))

result = r.getrange('name',0,2)  # 获取索引0到2的子序列
print("键name的0到2的子序列为:{}".format(result))

result = r.getrange('name',3,20)  # 获取索引3到20的子序列
print("键name的3到20的子序列为:{}".format(result))

#当前数据库中存在的键有:['test', 'k2', 'proxies:universal', 'name', 'k1']
#获取键name的值为:我们都是大帅哥
#键name的0到2的子序列为:我
#键name的3到20的子序列为:们都是大帅哥

注意:中文一个汉字占3个字节,如果取0到1的子序列,则会报错(不到一个汉字)

r.getrange('name',1,2)

#UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 0: invalid start byte

setrange(name, offset, value)

修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)

参数:

  • offset - 字符串的索引,字节(一个汉字三个字节)
  • value - 要设置的值

长度需要匹配,操作不匹配报错,再获取值也会报错

print("当前数据库中存在的键有:{}".format(r.keys()))
print("获取键name的值为:{}".format(r.get('name')))

print('将name的第一个字节开始的值改为“我”,占3个字节')
r.setrange('name',0,'我')  #
print("键name的值修改为:{}".format(r.get('name')))

#当前数据库中存在的键有:['test', 'k2', 'proxies:universal', 'name', 'k1']
#获取键name的值为:我们都是大帅哥
#将name的第一个字节开始的值改为“我”,占3个字节
#键name的值修改为:我们都是大帅哥
r.setrange('name',0,123456)  #
print("键name的值修改为:{}".format(r.get('name')))

#键name的值修改为:123456都是大帅哥
r.setrange('name',6,12)  
print("键name的值修改为:{}".format(r.get('name')))

#UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbd in position 8: invalid start byte

strlen(name)

返回name对应值的字节长度(一个汉字3个字节)

print("获取键test的值为:{}".format(r.get('test')))
result = r.strlen('test')
print("键test的字节长度为:{}".format(result))

print("获取键name的值为:{}".format(r.get('name')))
result = r.strlen('name')
print("键name的字节长度为:{}".format(result))

#获取键test的值为:12345
#键test的字节长度为:5
#获取键name的值为:我是一个大帅哥
#键name的字节长度为:21

incr(key, amount=1)

自增 key对应的值,当 key不存在时,则创建 key=amount,否则,则自增。

参数:amount - 自增数(必须是整数)

print("获取键num的值为:{}".format(r.get('num')))
print("获取键num1的值为:{}".format(r.get('num1')))

print("将键num的值增1")
r.incr('num',amount=1)
print("获取键num当前的值为:{}".format(r.get('num')))

r.incr('num1',amount=10)
print("获取键num1当前的值为:{}".format(r.get('num1')))

#获取键num的值为:None
#获取键num1的值为:None
#将键num的值增1
#获取键num当前的值为:1
#获取键num1当前的值为:10

decr(key, amount=1)

自减 key对应的值,当 key不存在时,则创建 name=amount,否则,则自减。

参数:amount - 自减数(整数)

append(key, value)

在key对应的值后面追加内容

参数:value - 要追加的字符串

redis 基本命令 list

增加一个或多个元素,没有就新建

  • lpush(name,values) :在name对应的list中添加元素,每个新的元素都添加到列表的最左边
  • rpush(name,values) :在name对应的list中添加元素,每个新的元素都添加到列表的最右边
r.delete('list1') # 删除键 list1

print("向list1中从左边依次添加 11 22 33")
r.lpush('list1',11,22,33)
print("list1的值为:{}".format(r.lrange('list1',0,2)))

print("向list1中从右边依次添加 44 55")
r.rpush('list1',44,55)
print("list1的值为:{}".format(r.lrange('list1',0,4)))

print('list1的长度为:{}'.format(r.llen('list1')))

'''
向list1中从左边依次添加 11 22 33
list1的值为:['33', '22', '11']
向list1中从右边依次添加 44 55
list1的值为:['33', '22', '11', '44', '55']
list1的长度为:5
'''

往已经有的name的列表中添加元素,没有的话无法创建

  • lpushx(name, value):往name列表的左边添加元素
  • rpushx(name, value):往name列表的右边添加元素
r.delete('list1') # 删除键 list1

print("向list1中从左边依次添加 11 22 33:")
r.lpush('list1',11,22,33)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("向list1中左边添加 44:")
r.lpushx('list1',44)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("向list1中右边添加 55:")
r.rpushx('list1',55)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

'''
向list1中从左边依次添加 11 22 33:
list1的值为:['33', '22', '11']
向list1中左边添加 44:
list1的值为:['44', '33', '22', '11']
向list1中右边添加 55:
list1的值为:['44', '33', '22', '11', '55']
'''

新增(固定索引号位置插入元素)

linsert(name, where, refvalue, value))
在name对应的列表的某一个值前或后插入一个新值

参数:

name - redis的name
where - BEFORE或AFTER
refvalue - 标杆值,即:在它前后插入数据
value - 要插入的数据

r.delete('list1') # 删除键 list1

print("向list1中从右边依次添加 11 22 33:")
r.rpush('list1',11,22,33)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("向list1中元素22的后面添加 44:")
r.linsert('list1','after',22,44)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

'''
向list1中从右边依次添加 11 22 33:
list1的值为:['11', '22', '33']
向list1中元素22的后面添加 44:
list1的值为:['11', '22', '44', '33']
'''

修改(指定索引号进行修改)

r.lset(name, index, value)

对name对应的list中的某一个索引位置重新赋值
参数:

  • name - redis的name
  • index - list的索引位置
  • value - 要设置的值
r.delete('list1') # 删除键 list1

print("向list1中从右边依次添加 11 22 33:")
r.rpush('list1',11,22,33)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("把list1中索引号为0的元素改为-11:")
r.lset('list1',0,-11)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

'''
向list1中从右边依次添加 11 22 33:
list1的值为:['11', '22', '33']
把list1中索引号为0的元素改为-11:
list1的值为:['-11', '22', '33']
'''

删除(指定值进行删除)

r.lrem(name, num, value)
在name对应的list中删除指定的值

参数:

name - redis的name
value - 要删除的值
num - num=0,删除列表中所有的指定值;
num=2 - 从前到后,删除2个, num=1,从前到后,删除左边第1个
num=-2 - 从后向前,删除2个

r.delete('list1') # 删除键 list1

print("向list1中从右边依次添加 11 22 11 11 44 11 11:")
r.rpush('list1',11,22,11,11,44,11,11)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("把list1中的元素11删掉:")
r.lrem('list1',2,11)  # 从左边删掉2个元素 11
print("删除元素后,list1的值为:{}".format(r.lrange('list1',0,-1)))

'''
向list1中从右边依次添加 11 22 11 11 44 11 11:
list1的值为:['11', '22', '11', '11', '44', '11', '11']
把list1中的元素11删掉:
删除元素后,list1的值为:['22', '11', '11', '44', '11', '11']
'''

删除并返回

  • lpop(name) : 在name对应的列表的左侧获取第一个元素并在列表中移除,返回删除的元素
  • rpop(name) : 在name对应的列表的右侧获取第一个元素并在列表中移除,返回删除的元素
r.delete('list1') # 删除键 list1

print("向list1中从右边依次添加 11 22 33 44 :")
r.rpush('list1',11,22,33,44)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("从左侧删除第一个元素,并返回删除的元素:")
result = r.lpop('list1')
print("删除的元素为:{}".format(result))
print("删除后list1的值为:{}".format(r.lrange('list1',0,-1)))

'''
向list1中从右边依次添加 11 22 33 44 :
list1的值为:['11', '22', '33', '44']
从左侧删除第一个元素,并返回删除的元素:
删除的元素为:11
删除后list1的值为:['22', '33', '44']
'''

除索引之外的值

ltrim(name, start, end)

在name对应的列表中移除没有在start-end索引之间的值

参数:

  • name - redis的name
  • start - 索引的起始位置
  • end - 索引结束位置
r.delete('list1') # 删除键 list1

print("向list1中从右边依次添加 11 22 33 44 55 :")
r.rpush('list1',11,22,33,44,55)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("删除索引 1-3之外的元素:")
r.ltrim('list1',1,3)
print("删除后list1的值为:{}".format(r.lrange('list1',0,-1)))

'''
向list1中从右边依次添加 11 22 33 44 55 :
list1的值为:['11', '22', '33', '44', '55']
删除索引 1-3之外的元素:
删除后list1的值为:['22', '33', '44']
'''

取值(根据索引号取值)

lindex(name, index) :在name对应的列表中根据索引获取列表元素

r.delete('list1') # 删除键 list1

print("向list1中从右边依次添加 11 22 33 44 55 :")
r.rpush('list1',11,22,33,44,55)
print("list1的值为:{}".format(r.lrange('list1',0,-1)))

print("索引为1的元素为:{}".format(r.lindex('list1',1)))

'''
向list1中从右边依次添加 11 22 33 44 55 :
list1的值为:['11', '22', '33', '44', '55']
索引为1的元素为:22
'''

移动 元素从一个列表移动到另外一个列表

rpoplpush(src, dst)
从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边

参数:

  • src - 要取数据的列表的 name
  • dst - 要添加数据的列表的 name

移动 元素从一个列表移动到另外一个列表 可以设置超时

brpoplpush(src, dst, timeout=0)
从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧

参数:

  • src - 取出并要移除元素的列表对应的name
  • dst - 要插入元素的列表对应的name
  • timeout - 当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞

一次移除多个列表

blpop(keys, timeout)
将多个列表排列,按照从左到右去pop对应列表的元素

参数:

  • keys - redis的name的集合
  • timeout - 超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
  • r.brpop(keys, timeout) 同 blpop,将多个列表排列,按照从右向左去移除各个列表内的元素
r.delete('list1') # 删除键 list1
r.delete('list2') # 删除键 list2

r.lpush("list1", 1, 2, 3, 4, 5)
r.lpush("list2", 11, 22, 33, 44, 55)
while r.llen('list2'):
    r.blpop(["list1", "list2"], timeout=2)
    print(r.lrange("list1", 0, -1), r.lrange("list2", 0, -1))
    
'''
['4', '3', '2', '1'] ['55', '44', '33', '22', '11']
['3', '2', '1'] ['55', '44', '33', '22', '11']
['2', '1'] ['55', '44', '33', '22', '11']
['1'] ['55', '44', '33', '22', '11']
[] ['55', '44', '33', '22', '11']
[] ['44', '33', '22', '11']
[] ['33', '22', '11']
[] ['22', '11']
[] ['11']
[] []
'''

redis基本命令 set

新增: sadd(name,values)

向集合中添加一个或多个元素

r.delete('set1') # 删除键 set1
r.sadd('set1',1,2,3,4,5)

# 获取集合元素个数
num = r.scard('set1')
print('集合set1的元素个数为:{}'.format(num))

print("获取集合set1的元素:{}".format(r.smembers('set1')))

print("获取集合中所有的成员--元组形式:")
result = r.sscan('set1')
print(result)

# 同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
print("获取集合中所有的成员--迭代器的方式:")
for i in r.sscan_iter("set1"):
    print(i)
    
'''
集合set1的元素个数为:5
获取集合set1的元素:{'3', '5', '1', '2', '4'}
获取集合中所有的成员--元组形式:
(0, ['1', '2', '3', '4', '5'])
获取集合中所有的成员--迭代器的方式:
1
2
3
4
5
'''

差集

*sdiff(keys, args):在第一个name对应的集合中且不在其他name对应的集合的元素集合

r.delete('set1') # 删除键 set1
r.delete('set2') # 删除键 set2
r.sadd('set1',1,2,3,4,5)
r.sadd('set2',1,2,6,7,5)

print("集合set1:{}".format(r.smembers('set1')))
print("集合set2:{}".format(r.smembers('set2')))

print("在集合set1但是不在集合set2中:{}".format(r.sdiff("set1", "set2")))
print("在集合set2但是不在集合set1中:{}".format(r.sdiff("set2", "set1")))

'''
集合set1:{'3', '5', '1', '2', '4'}
集合set2:{'6', '7', '5', '1', '2'}
在集合set1但是不在集合set2中:{'3', '4'}
在集合set2但是不在集合set1中:{'7', '6'}
'''

*sdiffstore(dest, keys, args) :获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中

r.delete('set1') # 删除键 set1
r.delete('set2') # 删除键 set2
r.sadd('set1',1,2,3,4,5)
r.sadd('set2',1,2,6,7,5)

print("集合set1:{}".format(r.smembers('set1')))
print("集合set2:{}".format(r.smembers('set2')))

r.sdiffstore("set3", "set1", "set2")    # 在集合set1但是不在集合set2中的元素,存入set3中
print("集合set3:{}".format(r.smembers('set3')))

'''
集合set1:{'3', '5', '1', '2', '4'}
集合set2:{'6', '7', '5', '1', '2'}
集合set3:{'3', '4'}
'''

交集

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

sinterstore(dest, keys, *args):获取多一个name对应集合的并集,再将其加入到dest对应的集合中

r.delete('set1') # 删除键 set1
r.delete('set2') # 删除键 set2
r.delete('set3') # 删除键 set3

r.sadd('set1',1,2,3,4,5)
r.sadd('set2',1,2,6,7,5)

print("集合set1:{}".format(r.smembers('set1')))
print("集合set2:{}".format(r.smembers('set2')))

print('集合set1和set2的交集:{}'.format(r.sinter("set1", "set2")))

r.sinterstore("set3", "set1", "set2")   # 在集合set1和set2中的交集,存入set3中
print("交集集合set3:{}".format(r.smembers('set3')))

'''
集合set1:{'3', '5', '1', '2', '4'}
集合set2:{'6', '7', '5', '1', '2'}
集合set1和set2的交集:{'5', '1', '2'}
交集集合set3:{'5', '1', '2'}
'''

并集

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

sunionstore(dest,keys, *args):获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中

判断是否是集合的成员 类似in

sismember(name, value):检查value是否是name对应的集合的成员,结果为True和False

移动

smove(src, dst, value):将某个成员从一个集合中移动到另外一个集合

r.delete('set1') # 删除键 set1
r.delete('set2') # 删除键 set2

r.sadd('set1',1,2,3)
r.sadd('set2',1,2,4,5)

print("集合set1:{}".format(r.smembers('set1')))
print("集合set2:{}".format(r.smembers('set2')))

r.smove("set1", "set2", 3)

print("移动后集合set1:{}".format(r.smembers('set1')))
print("移动后集合set2:{}".format(r.smembers('set2')))

'''
集合set1:{'3', '1', '2'}
集合set2:{'5', '1', '2', '4'}
移动后集合set1:{'1', '2'}
移动后集合set2:{'3', '5', '1', '2', '4'}
'''

删除

spop(name):从集合中随机删除一个元素,并返回

srem(name, values):删除指定值

r.delete('set1') # 删除键 set1

r.sadd('set1',1,2,3,4,5,6)

print("集合set1:{}".format(r.smembers('set1')))

result = r.spop("set1")
print("随机删除一个元素:{}".format(result))

print("删除后集合set1:{}".format(r.smembers('set1')))

print("删除集合set1的元素 6:{}".format(r.srem('set1',6)))
print("删除后集合set1:{}".format(r.smembers('set1')))

'''
集合set1:{'3', '6', '5', '1', '2', '4'}
随机删除一个元素:5
删除后集合set1:{'3', '6', '1', '2', '4'}
删除集合set1的元素 6:1
删除后集合set1:{'3', '1', '2', '4'}
'''

redis基本命令 有序set

Set操作,Set集合就是不允许重复的列表,本身是无序的。

有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。

新增

zadd(name, {‘k1’:v1,‘k2’:v2}):在name对应的有序集合中添加元素

zcard(name):获取name对应的有序集合元素的数量

r.delete('zset1') # 删除键 zset1
r.delete('zset2') # 删除键 zset2

r.zadd('zset1', {'n1':11,'n2':22})
r.zadd("zset2", {'m1':22, 'm2':44})
print("zset1集合的长度:{}".format(r.zcard("zset1"))) # 集合长度
print("zset2集合的长度:{}".format(r.zcard("zset2"))) # 集合长度
print("获取有序集合中 zset1 的所有元素:")
print(r.zrange("zset1", 0, -1))
print("获取有序集合中 zset2 的所有元素和分数:")
print(r.zrange("zset2", 0, -1, withscores=True))

'''
zset1集合的长度:2
zset2集合的长度:2
获取有序集合中 zset1 的所有元素:
['n1', 'n2']
获取有序集合中 zset2 的所有元素和分数:
[('m1', 22.0), ('m2', 44.0)]
'''

获取有序集合的所有元素

r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

按照索引范围获取name对应的有序集合的元素

参数:

  • name - redis的name
  • start - 有序集合索引起始位置(非分数)
  • end - 有序集合索引结束位置(非分数)
  • desc - 排序规则,默认按照分数从小到大排序
  • withscores - 是否获取元素的分数,默认只获取元素的值
  • score_cast_func - 对分数进行数据转换的函数

从大到小排序(同zrange,集合是从大到小排序的)
zrevrange(name, start, end, withscores=False, score_cast_func=float)

r.delete('zset1') # 删除键 zset1
r.delete('zset2') # 删除键 zset2

r.zadd('zset1', {'n1':11,'n2':22,'n3':10,'n4':33})
r.zadd("zset2", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print("获取有序集合中 zset1 的所有元素:")
print(r.zrevrange("zset1", 0, -1))
print("获取有序集合中 zset2 的所有元素和分数:")
print(r.zrevrange("zset2", 0, -1, withscores=True))  # 分数倒序

'''
获取有序集合中 zset1 的所有元素:
['n4', 'n2', 'n1', 'n3']
获取有序集合中 zset2 的所有元素和分数:
[('m5', 55.0), ('m2', 44.0), ('m3', 30.0), ('m1', 22.0), ('m4', 10.0)]
'''

按照分数范围获取name对应的有序集合的元素

zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print("获取有序集合zset1中,分数在10-30的元素和分数:")
print(r.zrangebyscore("zset1", 10,30,withscores=True))  # 分数从小到大

获取有序集合zset1中,分数在10-30的元素和分数:
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0)]

'''
获取有序集合zset1中,分数在10-30的元素和分数:
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0)]
'''

按照分数范围获取有序集合的元素并排序(默认从大到小排序)

zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print("获取有序集合zset1中,分数在30-50的元素和分数:")
print(r.zrevrangebyscore("zset1", 50,30,withscores=True))  # 分数从大到小

#获取有序集合zset1中,分数在30-50的元素和分数:
#[('m2', 44.0), ('m3', 30.0)]

获取所有元素–默认按照分数顺序排序

zscan(name, cursor=0, match=None, count=None, score_cast_func=float)

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print("获取有序集合zset1的所有元素和分数,以元组形式返回:")
print(r.zscan("zset1"))  # 分数从小到大

'''
获取有序集合zset1的所有元素和分数,以元组形式返回:
(0, [('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m2', 44.0), ('m5', 55.0)])
'''

获取所有元素–迭代器

zscan_iter(name, match=None, count=None,score_cast_func=float)

for i in r.zscan_iter("zset3"): # 遍历迭代器
    print(i)

统计个数

zcount(name, min, max):获取name对应的有序集合中分数 在 [min,max] 之间的个数

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print(r.zrange("zset1", 0, -1, withscores=True))
print(r.zcount("zset1", 11, 50))

'''
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m2', 44.0), ('m5', 55.0)]
3
'''

自增

zincrby(name, amount, value):自增name对应的有序集合的 value 对应的分z数

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print(r.zrange("zset1", 0, -1, withscores=True))

r.zincrby("zset1", 2, 'm2')    # 每次将m2的分数自增2
print(r.zrange("zset1", 0, -1, withscores=True))

'''
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m2', 44.0), ('m5', 55.0)]
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m2', 46.0), ('m5', 55.0)]
'''

获取值的索引号

zrank(name, value):获取某个值在 name对应的有序集合中的索引(从 0 开始)

zrevrank(name, value),获取某个值在 name对应的有序集合中的索引(从大到小排序)

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print(r.zrange("zset1", 0, -1, withscores=True))

print('m2的索引号是3,这里按照分数顺序(从小到大):{}'.format(r.zrank("zset1", "m2")))
print('m2的索引号是1,这里安照分数倒序(从大到小):{}'.format(r.zrevrank("zset1", "m2")))

'''
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m2', 44.0), ('m5', 55.0)]
m2的索引号是3,这里按照分数顺序(从小到大):3
m2的索引号是1,这里安照分数倒序(从大到小):1
'''

删除

zrem(name, values):删除name对应的有序集合中值是values的成员

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print("有序集合zset1:")
print(r.zrange("zset1", 0, -1, withscores=True))

r.zrem('zset1','m2') # 删除 m2 元素
print("删除m2元素后,有序集合zset1:")
print(r.zrange("zset1", 0, -1, withscores=True))

'''
有序集合zset1:
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m2', 44.0), ('m5', 55.0)]
删除m2元素后,有序集合zset1:
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m5', 55.0)]
'''

zremrangebyrank(name, min, max):根据排行范围删除,按照索引号来删除

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print("有序集合zset1:")
print(r.zrange("zset1", 0, -1, withscores=True))

r.zremrangebyrank("zset1", 1, 3)  # 删除有序集合中的索引号是1到3的元素
print("删除元素后,有序集合zset1:")
print(r.zrange("zset1", 0, -1, withscores=True))

'''
有序集合zset1:
[('m4', 10.0), ('m1', 22.0), ('m3', 30.0), ('m2', 44.0), ('m5', 55.0)]
删除元素后,有序集合zset1:
[('m4', 10.0), ('m5', 55.0)]
'''

zremrangebyscore(name, min, max):根据分数范围删除

获取值对应的分数

r.delete('zset1') # 删除键 zset1

r.zadd("zset1", {'m1':22, 'm2':44, 'm3':30, 'm4':10, 'm5':55})

print("有序集合zset1:")
print(r.zrange("zset1", 0, -1, withscores=True))

print('获取元素m4对应的分数:{}'.format(r.zscore("zset1", "m4")))

redis 基本命令 hash

单个增加–修改(单个取出)–没有就新增,有的话就修改

hset(name, key, value)
name对应的hash中设置一个键值对(不存在,则创建;否则,修改)

参数:

  • name - redis的name
  • key - name对应的hash中的key
  • value - name对应的hash中的value
  • 注:hsetnx(name, key, value) 当name对应的hash中不存在当前key时则创建(相当于添加)
r.delete('zset1') # 删除键 zset1

r.hset("hash1", "k1", "v1")
r.hset("hash1", "k2", "v2")
print(r.hkeys("hash1")) # 取hash中所有的key
print(r.hget("hash1", "k1"))    # 单个取hash的key对应的值
print(r.hmget("hash1", "k1", "k2")) # 多个取hash的key对应的值

'''
['k1', 'k2']
v1
['v1', 'v2']
'''

取出所有键值对

hgetall(name):获取name对应hash的所有键值

r.delete('hash1') # 删除键 hash1

r.hset("hash1", "k1","v1")
r.hset("hash1", "k2","v2")
r.hset("hash1", "k3","v3")

print(r.hgetall("hash1"))

'''
print(r.hgetall("hash1"))
'''

其他常用命令

命令 描述
hlen(name) 获取name对应的hash中键值对的个数
hkeys(name) 得到所有的keys
hvals(name) 得到所有的value
hexists(name, key) 判断成员是否存在
hdel(name,*keys) 删除键值对

自增自减整数(将key对应的value–整数 自增1或者2,或者别的整数 负数就是自减)

hincrby(name, key, amount=1)
自增name对应的hash中的指定key的值,不存在则创建key=amount

参数:

name - redis中的name
key - hash对应的key
amount - 自增数(整数)

自增自减浮点数(将key对应的value–浮点数 自增1.0或者2.0,或者别的浮点数 负数就是自减)

hincrbyfloat(name, key, amount=1.0)
自增name对应的hash中的指定key的值,不存在则创建key=amount

参数:

  • name - redis中的name
  • key - hash对应的key
  • amount,自增数(浮点数)
  • 自增 name 对应的 hash 中的指定 key 的值,不存在则创建 key=amount

取值查看–分片读取

hscan(name, cursor=0, match=None, count=None)
增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆

参数:

  • name - redis的name
  • cursor - 游标(基于游标分批取获取数据)
  • match - 匹配指定key,默认None 表示所有的key
  • count - 每次分片最少获取个数,默认None表示采用Redis的默认分片个数

hscan_iter(name, match=None, count=None)

利用yield封装hscan创建生成器,实现分批去redis中获取数据

参数:

  • match - 匹配指定key,默认None 表示所有的key
  • count - 每次分片最少获取个数,默认None表示采用Redis的默认分片个数

管道(pipeline)

redis默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。

管道(pipeline)是redis在提供单个请求中缓冲多条服务器命令的基类的子类。它通过减少服务器-客户端之间反复的TCP数据库包,从而大大提高了执行批量命令的功能

pipe = r.pipeline() # 创建一个管道

pipe.set('name', 'jack')
pipe.set('role', 'sbhh')
pipe.sadd('faz', 'baz')
pipe.incr('num')    # 如果num不存在则vaule为1,如果存在,则value自增1
pipe.execute()

print(r.get("name"))
print(r.get("role"))
print(r.get("num"))

'''
jack
sbhh
2
'''

管道的命令可以写在一起:

pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute()
print(r.get("name"))
print(r.get("role"))
print(r.get("num"))

'''
jack
sbhh
4
'''

其它常用操作

操作 描述

  1. delete(key) 根据删除redis中的任意数据类型的key
  2. exists(name) 检测redis的name是否存在,存在就是True,False不存在
  3. expire(name ,time) 为某个redis的某个name设置超时时间
  4. rename(src, dst) 对redis的name重命名
  5. randomkey() 随机获取一个redis的name(不删除)
  6. type(name) 获取name对应值的类型
  7. dbsize() 当前redis包含多少条数据
  8. save() 检查点"操作,将数据写回磁盘。保存时阻塞
  9. flushdb() 清空redis中的所有数据

你可能感兴趣的:(Python,redis,python,数据库)