You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
python/Other/Python3 操作 Redis.md

1336 lines
37 KiB

### Python3 操作 Redis
#### 1、简单介绍
redis是一个key-value存储系统和Memcached类似。它支持存储的value类型相对更多包括string(字符串)、list(链表、set(集合)、zset(sorted set --有序集合)和hash哈希类型
这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作而且这些操作都是原子性的。在此基础上redis支持各种不同方式的排序。
与memcached一样为了保证效率数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件并且在此基础上实现了master-slave(主从)同步。
```
1. 使用Redis有哪些好处
(1) 速度快因为数据存在内存中类似于HashMapHashMap的优势就是查找和操作的时间复杂度都是O(1)
(2) 支持丰富数据类型支持stringlistsetsorted sethash
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性可用于缓存消息按key设置过期时间过期后将会自动删除
```
#### 2、安装 redis 软件
```shell
yum install redis #需要epel源
systemctl start redis
```
**命令列表**
```shell
redis-server # Redis 服务器
redis-cli # Redis 自带的客户端
redis-benchmark # Redis 性能测试工具
redis-check-aof # AOF 文件修复工具
```
**Redis 默认监听 6379 端口**
#### 3、Redis 命令
Redis 命令用于在 redis 服务上执行操作。
要在 redis 服务上执行命令需要一个 redis 客户端。Redis 客户端在我们之前下载的的 redis 的安装包中。
语法
Redis 客户端的基本语法为:
```
$ redis-cli
```
以下实例讲解了如何启动 redis 客户端:
启动 redis 客户端,打开终端并输入命令 **redis-cli**。该命令会连接本地的 redis 服务。
```
$redis-cli
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING
PONG
```
在以上实例中我们连接到本地的 redis 服务并执行 **PING** 命令,该命令用于检测 redis 服务是否启动。
------
##### 在远程服务上执行命令
如果需要在远程 redis 服务上执行命令,同样我们使用的也是 **redis-cli** 命令。
语法
```
$ redis-cli -h host -p port -a password
```
以下实例演示了如何连接到主机为 127.0.0.1,端口为 6379 ,密码为 mypass 的 redis 服务上。
```
$redis-cli -h 127.0.0.1 -p 6379 -a "mypass"
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING
PONG
```
#### 4、Redis 数据类型
Redis支持五种数据类型string字符串hash哈希list列表set集合及zset(sorted set有序集合)。
------
##### 1、String字符串
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型string 类型的值最大能存储 512MB。
```
redis 127.0.0.1:6379> SET name "qianfeng"
OK
redis 127.0.0.1:6379> GET name
"qianfeng"
```
在以上实例中我们使用了 Redis 的 **SET****GET** 命令。键为 name对应的值为 **qianfeng**
**注意:**一个键最大能存储512MB。
------
##### 2、Hash哈希
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表hash 特别适合用于存储对象。
**DEL qianfeng** 用于删除前面测试用过的 key不然会报错**(error) WRONGTYPE Operation against a key holding the wrong kind of value**
```
redis 127.0.0.1:6379> DEL qianfeng
redis 127.0.0.1:6379> HMSET myhash field1 "Hello" field2 "World"
"OK"
redis 127.0.0.1:6379> HGET myhash field1
"Hello"
redis 127.0.0.1:6379> HGET myhash field2
"World"
```
实例中我们使用了 Redis **HMSET, HGET** 命令,**HMSET** 设置了两个 **field=>value** 对, HGET 获取对应 **field** 对应的 **value**
每个 hash 可以存储 2**32-1 键值对40多亿
##### 3、List列表
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
```
redis 127.0.0.1:6379> lpush qianfeng redis
(integer) 1
redis 127.0.0.1:6379> lpush qianfeng mongodb
(integer) 2
redis 127.0.0.1:6379> lpush qianfeng rabitmq
(integer) 3
redis 127.0.0.1:6379> lrange qianfeng 0 10
1) "rabitmq"
2) "mongodb"
3) "redis"
redis 127.0.0.1:6379>
```
在以上实例中我们使用了 **LPUSH** 将三个值插入了名为 **qianfeng** 的列表当中。
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。
##### 4、Set集合
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的所以添加删除查找的复杂度都是0(1)。
###### 1、sadd 命令
添加一个 string 元素到 key 对应的 set 集合中成功返回1如果元素已经在集合中返回 0如果 key 对应的 set 不存在则返回错误。
```
sadd key member
```
```
redis 127.0.0.1:6379> sadd qianfeng1 redis
(integer) 1
redis 127.0.0.1:6379> sadd qianfeng1 mongodb
(integer) 1
redis 127.0.0.1:6379> sadd qianfeng1 rabitmq
(integer) 1
redis 127.0.0.1:6379> sadd qianfeng1 rabitmq
(integer) 0
redis 127.0.0.1:6379> smembers qianfeng1
1) "redis"
2) "rabitmq"
3) "mongodb"
```
**注意:**以上实例中 rabitmq 添加了两次,但根据集合内元素的唯一性,第二次插入的元素将被忽略。
集合中最大的成员数为 2**32 - 1(4294967295, 每个集合可存储40多亿个成员)。
##### 5、zset(sorted set有序集合)
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的所以添加删除查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。。
```
double 和 float 的区别是 double精度高有效数字16位float精度7位。但double消耗内存是float的两倍double的运算速度比float慢得多
```
###### 1、zadd 命令
添加元素到集合元素在集合中存在则更新对应score
```
zadd key score member
```
```redis
redis 127.0.0.1:6379> ZADD qianfengkey 1 redis
(integer) 1
redis 127.0.0.1:6379> ZADD qianfengkey 2 mongodb
(integer) 1
redis 127.0.0.1:6379> ZADD qianfengkey 3 mysql
(integer) 1
redis 127.0.0.1:6379> ZADD qianfengkey 3 mysql
(integer) 0
redis 127.0.0.1:6379> ZADD qianfengkey 4 mysql
(integer) 0
redis 127.0.0.1:6379> ZRANGE qianfengkey 0 10 WITHSCORES
1) "redis"
2) "1"
3) "mongodb"
4) "2"
5) "mysql"
6) "4"
```
在以上实例中我们通过命令 **ZADD** 向 redis 的有序集合中添加了三个值并关联上分数。
#### 5、Python 操作 Redis
所见即所得的东西,讲一部分,其他按照笔记看。不要求都掌握。
##### 1、安装包
```shell
pip3 install redis
```
##### 2、连接
```python
In [1]: import redis
In [2]: r = redis.Redis(host='10.18.42.174', port=6379)
In [3]: r.set("QF", "www.qfedu.com")
Out[3]: True
In [4]: r.get("QF")
Out[4]: b'www.qfedu.com'
In [5]: ret = r.get("QF")
In [6]: ret.decode()
Out[6]: 'www.qfedu.com'
```
##### 3、连接池
redis-py使用connection pool来管理对一个redis server的所有连接避免每次建立、释放连接的开销。
默认每个Redis实例都会维护一个自己的连接池。
可以直接建立一个连接池然后作为参数传给Redis这样就可以实现多个 Redis 实例共享一个连接池
```python
In [12]: pool = redis.ConnectionPool(host='172.16.153.134', port=6379)
In [13]: rs = redis.Redis(connection_pool=pool)
In [14]: rs.set("foo", "bar")
Out[14]: True
In [15]: rs.get("foo")
Out[15]: b'bar'
```
##### 4、基本操作
- ##### **String 操作**
redis中的 String 在内存中按照一个name对应一个value来存储
```python
set(name, value, ex=None, px=None, nx=False, xx=False)
set()
"""
在 Redis 中设置值,默认,不存在则创建,存在则修改
参数:
ex过期时间
px过期时间毫秒
nx假如设置为True则只有 name 不存在时,当前 set 操作才执行
xx假如设置为True则只有 name 存在时,当前 set 操作才执行
"""
setnx(name, value)
# 设置值只有name不存在时执行设置操作添加
setex(name, time, value)
"""
设置值
参数:
time过期时间数字秒
"""
psetex(name, time_ms, value)
"""
设置值
参数:
time_ms过期时间数字毫秒
"""
mset(*args, **kwargs)
"""
批量设置值:
mset(QF='www.qfedu.com', yangge='杨哥')
mget({'k1': 'v1', 'k2': 'v2'})
"""
get(name)
# 获取值
mget(keys, *args)
"""
批量获取:
mget('QF', 'foo')
mget(['QF', 'foo'])
"""
getset(name, value)
# 设置新值并获取原来的值
getrange(key, start, end)
# 以字节的方式获取一部分值(一个汉字等于三个字节)
setrange(name, offset, value)
"""
修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
参数:
offset 字符串的索引,字节方式
"""
incr(self, name, amount=1)
"""
自增 name对应的值当name不存在时则创建 nameamount否则则自增。
参数:
name,Redis的name
amount,自增数(必须是整数)
"""
decr(self, name, amount=1)
# 自减
append(key, value)
# 在redis name对应的值后面追加内容
```
- ##### **Hash 操作**
```python
hset(name, key, value)
#*************************
In [20]: rs.hset("hs1","k1", "v1")
Out[20]: 0
#*************************
"""
name 对应的 hash 中设置一个键值对(不存在,则创建;否则,修改)
参数:
nameredis hash的name
keyname对应的hash中的key
valuename对应的hash中的value
注意:
# hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建相当于添加
"""
hmset(name, mapping)
#*************************
In [6]: rs.hmset('hs1', {'k1':'v1', 'k2': 'v2'})
Out[6]: True
#*************************
"""
在name对应的hash中批量设置键值对没有的 key 就创建,已存在的 key 修改
参数:
mapping字典栗子{'k1':'v1', 'k2': 'v2'}
"""
hget(name,key)
#*************************
In [8]: rs.hget('hs1','k1')
Out[8]: b'v1'
#*************************
# 在name对应的hash中获取根据key获取value
hmget(name, keys, *args)
"""
在name对应的hash中获取多个key的值
参数:
namereids对应的name
keys要获取key集合栗子['k1', 'k2', 'k3']
*args要获取的key栗子k1,k2,k3
栗子:
r.mget('xx', ['k1', 'k2'])
r.hmget('xx', 'k1', 'k2')
"""
################### 下面的自己搞 ########################
hgetall(name)
# 获取name对应hash的所有键值
hlen(name)
# 获取name对应的hash中键值对的个数
hkeys(name)
# 获取name对应的hash中所有的key的值
hvals(name)
# 获取name对应的hash中所有的value的值
hexists(name, key)
# 检查name对应的hash是否存在当前传入的key
hdel(name,*keys)
# 将name对应的hash中指定key的键值对删除
hincrby(name, key, amount=1)
"""
自增name对应的hash中的指定key的值不存在则创建key=amount
参数:
nameredis中的name
key hash对应的key
amount自增数整数
"""
hincrbyfloat(name, key, amount=1.0)
"""
自增name对应的hash中的指定key的值不存在则创建key=amount
参数:
nameredis中的name
key hash对应的key
amount自增数浮点数
"""
# 更多 http://redisdoc.com/key/scan.html#scan
```
- ##### **List 操作**
```python
lpush(name,values)
"""
在name对应的list中添加元素每个新的元素都添加到列表的最左边
栗子:
r.lpush('oo', 11,22,33)
保存顺序为: 33,22,11
扩展:
rpush(name, values) 表示从右向左操作
"""
lpushx(name,value)
"""
在name对应的list中添加元素只有name已经存在时值添加到列表的最左边
更多:
rpushx(name, value) 表示从右向左操作
"""
llen(name)
# name对应的list元素的个数
linsert(name, where, refvalue, value))
"""
在name对应的列表的某一个值前或后插入一个新值
参数:
nameredis的name
whereBEFORE或AFTER
refvalue标杆值在它前后插入数据
value要插入的数据
"""
r.lset(name, index, value)
"""
对name对应的list中的某一个索引位置重新赋值
参数:
nameredis的name
indexlist的索引位置
value要设置的值
"""
r.lrem(name, value, num)
"""
在name对应的list中删除指定的值
参数:
nameredis的name
value要删除的值
num num=0删除列表中所有的指定值
num=2,从前到后删除2个
num=-2,从后向前删除2个
"""
lpop(name)
"""
在name对应的列表的左侧获取第一个元素并在列表中移除返回值则是第一个元素
扩展:
# rpop(name) 表示从右向左操作
"""
lindex(name, index)
"""
在name对应的列表中根据索引获取列表元素
lrange(name, start, end)
在name对应的列表分片获取数据
参数:
nameredis的name
start索引的起始位置
end索引结束位置
"""
ltrim(name, start, end)
"""
在name对应的列表中移除没有在start-end索引之间的值
参数:
nameredis的name
start索引的起始位置
end索引结束位置
"""
rpoplpush(src, dst)
"""
从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
参数:
src要取数据的列表的name
dst要添加数据的列表的name
"""
blpop(keys, timeout)
"""
将多个列表排列按照从左到右去pop对应列表的元素
参数:
keysredis的name的集合
timeout超时时间当元素所有列表的元素获取完之后阻塞等待列表内有数据的时间, 0 表示永远阻塞
扩展:
r.brpop(keys, timeout),从右向左获取数据
"""
brpoplpush(src, dst, timeout=0)
"""
从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
参数:
src取出并要移除元素的列表对应的name
dst要插入元素的列表对应的name
timeout当src对应的列表中没有数据时阻塞等待其有数据的超时时间0 表示永远阻塞
"""
######### 自定义增量迭代 #########
"""
由于redis类库中没有提供对列表元素的增量迭代假如想要循环name对应的列表的所有元素那么就需要
1、获取name对应的所有列表
2、循环列表
但是,假如列表非常大,那么就有可能在第一步时就将程序的内容撑爆,所有有必要自定义一个增量迭代的功能:
"""
def list_iter(name):
"""
自定义redis列表增量迭代
:param name: redis中的name
:return: yield 返回 列表元素
"""
list_count = r.llen(name)
for index in xrange(list_count):
yield r.lindex(name, index)
# 使用
for item in list_iter('pp'):
print(item)
```
- ##### **Set 操作**
也是列表形式,但是其内的元素不允许重复
```python
sadd(name,values)
# name对应的集合中添加元素
scard(name)
# 获取name对应的集合中元素个数
sdiff(keys, *args)
# 差集在第一个name对应的集合中且不在其他name对应的集合的元素集合
sdiffstore(dest, keys, *args)
# 获取第一个name对应的集合中且不在其他name对应的集合再将其新加入到dest对应的集合中
sinter(keys, *args)
# 获取一个name对应集合的交集
sinterstore(dest, keys, *args)
# 获取多一个name对应集合的并集再讲其加入到dest对应的集合中
sismember(name, value)
# 检查value是不是name对应的集合的成员
smembers(name)
# 获取name对应的集合的所有成员
smove(src, dst, value)
# 将某个成员从一个集合中移动到另外一个集合
spop(name)
# 从集合的右侧(尾部)移除一个成员,并将其返回
srandmember(name, numbers)
# 从name对应的集合中随机获取 numbers 个元素
srem(name, values)
# 在name对应的集合中删除某些值
sunion(keys, *args)
# 获取多一个name对应的集合的并集
sunionstore(dest,keys, *args)
# 获取多一个name对应的集合的并集并将结果保存到dest对应的集合中
```
- ##### **Sort Set 操作**
有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
```python
zadd(name, *args, **kwargs)
"""
在 name 对应的有序集合中添加元素
例如:
zadd('something', 'n1', 1, 'n2', 2)
zadd('something', n1=11, n2=22)
"""
zcard(name)
# 获取name对应的有序集合元素的数量
zcount(name, min, max)
# 获取name对应的有序集合中分数 在 [min,max] 之间的个数
zincrby(name, value, amount)
# 自增name对应的有序集合的 name 对应的分数
r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
"""
按照索引范围获取name对应的有序集合的元素
参数:
nameredis的name
start有序集合索引起始位置非分数
end有序集合索引结束位置非分数
desc排序规则默认按照分数从小到大排序
withscores是否获取元素的分数默认只获取元素的值
score_cast_func对分数进行数据转换的函数
更多:
从大到小排序
zrevrange(name, start, end, withscores=False, score_cast_func=float)
按照分数范围获取name对应的有序集合的元素
zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
从大到小排序
zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
"""
zrank(name, value)
"""
获取某个值在 name对应的有序集合中的排行从 0 开始)
更多:
zrevrank(name, value),从大到小排序
"""
zrangebylex(name, min, max, start=None, num=None)
"""
当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的 值 lexicographical ordering来进行排序而这个命令则可以返回给定的有序集合键 key 中, 元素的值介于 min 和 max 之间的成员
对集合中的每个成员进行逐个字节的对比byte-by-byte compare 并按照从低到高的顺序, 返回排序后的集合成员。 如果两个字符串有一部分内容是相同的话, 那么命令会认为较长的字符串比较短的字符串要大
参数:
nameredis的name
min左区间。 + 表示正无限; - 表示负无限; ( 表示开区间; [ 则表示闭区间
min右区间
start对结果进行分片处理索引位置
num对结果进行分片处理索引后面的num个元素
例子:
ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga
r.zrangebylex('myzset', "-", "[ca") 结果为:['aa', 'ba', 'ca']
扩展:
从大到小排序
zrevrangebylex(name, max, min, start=None, num=None)
"""
zrem(name, values)
# 删除name对应的有序集合中值是values的成员
# 如zrem('zz', ['s1', 's2'])
zremrangebyrank(name, min, max)
# 根据排行范围删除
zremrangebyscore(name, min, max)
# 根据分数范围删除
zremrangebylex(name, min, max)
# 根据值返回删除
zscore(name, value)
# 获取name对应有序集合中 value 对应的分数
zinterstore(dest, keys, aggregate=None)
# 获取两个有序集合的交集如果遇到相同值不同分数则按照aggregate进行操作
# aggregate的值为: SUM MIN MAX
zunionstore(dest, keys, aggregate=None)
# 获取两个有序集合的并集如果遇到相同值不同分数则按照aggregate进行操作
# aggregate的值为: SUM MIN MAX
```
#### 6、发布和订阅
##### 1、**发布者**
```python
import redis
pool = redis.ConnectionPool(host='172.16.153.136',
port=6379,
max_connections=10)
conn = redis.Redis(connection_pool=pool)
conn.publish('fm101', '我要上头条')
```
##### **2、订阅者**
```python
import redis
pool = redis.ConnectionPool(host='172.16.153.136',
port=6379,
max_connections=10)
conn = redis.Redis(connection_pool=pool)
pub = conn.pubsub()
pub.subscribe('fm101')
while True:
data = pub.parse_response()
print(data)
```
#### 7、python链接redis操作作业练习
```python
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令StrictRedis用于实现大部分官方的命令并使用官方的语法和命令Redis是StrictRedis的子类用于向后兼容旧版本的redis-py。
```
```python
import redis
#创建redis链接对象
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
#存储键值对
r.set('site','www.qi.cn')
#获取值
print(r.get('site'))
#指定decode_responses为True表示输出为字符串
red = redis.StrictRedis(host='127.0.0.1',port=6379,decode_responses=True)
#默认redis入库编码是utf-8如果要修改的话需要指明 charset 和 decode_responsers 为True
#test = redis.StrictRedis(host='localhost', port=6379, db=0, password=None, socket_timeout=None, connection_pool=None, charset='utf-8', errors='strict', decode_responses=False, unix_socket_path=None)
red.lpush('list1','mongdb','redis','mysql')
print(r.lrange('list1',0,-1))
print(r.llen('list1'))
#output:
www.qi.cn
['mysql', 'redis', 'mongdb']
3
```
连接池:
redis-py使用connection pool来管理对一个redis server的所有连接避免每次建立、释放连接的开销。默认每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池然后作为参数Redis这样就可以实现多个Redis实例共享一个连接池。
```python
import redis
#创建连接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379,decode_responses=True)
#创建链接对象
r=redis.Redis(connection_pool=pool)
#设置集合
r.sadd('set1','v1','v2','v3')
r.sadd('set1','v2')
#显示集合的值
print(r.smembers('set1'))
#使用strictRedis连接池
rs = redis.StrictRedis(connection_pool=pool)
r.lpush('l1','python','memcache','redis','mongodb')
print(r.lrange('l1',0,-1))
#output:
{'v3', 'v1', 'v2'}
['mongodb', 'redis', 'memcache', 'python']
```
##### 1数据string操作
redis中的String在在内存中按照一个name对应一个value来存储的。
set key value [EX seconds] [PX milliseconds] [NX|XX]
参数:
```python
ex过期时间
px过期时间毫秒
nx如果设置为``True``则只有name不存在时当前``set``操作才执行
xx如果设置为``True``则只有name存在时岗前``set``操作才执行
```
```python
import redis
#创建连接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379,decode_responses=True)
#创建链接对象
r=redis.Redis(connection_pool=pool)
r.set('test','dddddddddddd',ex=3,nx=True)
print(r.get('test'))
```
setnx(name,value)设置值只有在name不存在是才执行操作
setex(name,value,time):设置值过期时间,单位为秒
psetex(name,time_ms,value):设置值,过期时间为毫秒
mset(*args,**kwargs):批量设置多个值
get(name):获取值
getrange(key,start,end):获取子序列,根据字节获取
setrange(name,oofset,value):修改字符串内容,从指定字符串索引开始向后替换
```python
import redis
#创建连接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379,decode_responses=True)
#创建链接对象
r=redis.Redis(connection_pool=pool)
r.set('test','12345',nx=True)
r.setrange('test',0,'8888')
print(r.get('test'))
```
setbit(name,offset,value)对name对应值的二进制表示的位进行操作
getbit(name,offset)获取name对应的二进制位表示的值只能是0或1
```python
import redis
r=redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.set('name','p')
print(r.get('name'))
#打印p,q对应的ascii码
print(ord('p'),ord('q'))
#打印ascii码对应的二进制
print(bin(ord('p')),bin(ord('q')))
print('修改前7位的值',r.getbit('name','7'))
#设置二进制位的第7位为1相当于移动ascii码位112为113对应的字符为q
r.setbit('name','7','1')
print('修改后7位的值',r.getbit('name','7'))
print(r.get('name'))
#output
p
112 113
0b1110000 0b1110001
修改前7位的值 0
修改后7位的值 1
q
```
strlen(name)返回name对应值的字节长度一个汉字3个字节
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.set('name','python')
print(r.strlen('name')) #输出6个字节
```
incr(self,name,amount=1)自增name对应的值当name不存在时则创建name=amount否则自增
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
#r.set('name','python')
r.set('age','1')
print(r.incr('age','3')) #结果为4
```
decr(self,name,amount=1):自减 name对应的值当name不存在时则创建nameamount否则则自减
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.set('age','10')
print(r.decr('age','3')) #输出为7
```
append(key,value)在name对应的值后面追加内容
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.set('age','10')
print(r.get('age'))
print(r.append('age','11'))
print(r.get('age'))
#output
10
4
1011
```
##### 2hash操作
hset(name,key,value)在name对应的hash中设置一个键值对不存在则创建否则修改
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.hset('haset','python','3.5')
print(r.hget('haset','python'))
r.hset('haset','redis','1.8')
print(r.hgetall('haset'))
#output
3.5
{'python': '3.5', 'redis': '1.8'}
```
hmset(name,mapping)在name对应的hash中批量设置键值对
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.hmset('hashmore',{'k1':'v1','k2':'v2','k3':'v3'})
print(r.hmget('hashmore','k1','k2','k3'))
print(r.hgetall('hashmore'))
```
hget(name,key)获取hash中的value
hmget(name,keys,*args)获取过个hash的key的值
hgetall(name)获取hash的所有键值对
hlen(name)获取hash中键值对的个数
hkeys(name)获取hash中所有keys的值
hvals(name):获取hash中所有value的值
hexists(name,key)检查hash中是否存在key
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.hmset('hashmore',{'k1':'v1','k2':'v2','k3':'v3'})
print(r.hmget('hashmore','k1','k2','k3'))
print(r.hgetall('hashmore'))
print(r.hexists('hashmore','k2'))
print(r.hexists('hashmore','k4'))
#output
['v1', 'v2', 'v3']
{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
True
False
```
hdel(name,*key)删除hash中的key
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.hmset('hashmore',{'k1':'v1','k2':'v2','k3':'v3'})
print(r.hgetall('hashmore'))
print(r.hdel('hashmore','k3'))
print(r.hgetall('hashmore'))
#output
{'k3': 'v3', 'k2': 'v2', 'k1': 'v1'}
1
{'k2': 'v2', 'k1': 'v1'}
```
hincrby(name,key,amount=1)自增hash中指定的key的值不存在则创建key=amount
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.hmset('hashmore',{'k1':'1','k2':'2','k3':'3'})
print(r.hgetall('hashmore'))
r.hincrby('hashmore','k1','2')
print(r.hgetall('hashmore'))
```
hincrbyfloat(name,key,amount=1.0)自增hash中指定的key的值同上针对浮点数
hscan(name,cursor=0,match=None,count=None)增量迭代获取hash中数据cursor游标match匹配key默认所有count获取的个数。
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.hmset('hashmore',{'k1':'1','k2':'2','k3':'3','k4':'4'})
print(r.hgetall('hashmore'))
print(r.hscan('hashmore',cursor=2,match='k2',count=1))
print(r.hscan('hashmore',count=4))
#output
```
{'k1': '1', 'k3': '3', 'k2': '2', 'k4': '4'}
(0, {'k2': '2'})
(0, {'k1': '1', 'k3': '3', 'k2': '2', 'k4': '4'})
hscan_iter(name,match=None,count=None)利用yield封装hscan创建生成器实现分批获取数据
```python
import redis
r= redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.hmset('hashmore',{'k1':'1','k2':'2','k3':'3','k4':'4','k5':'5','k6':'6','k7':'7','k8':'8'})
oo = r.hscan_iter('hashmore')
print(next(oo))
print(next(oo))
print(next(oo))
print(next(oo))
#output:
('k2', '2')
('k7', '7')
('k8', '8')
('k5', '5')
```
##### 3list操作
lpush(name,values):在列表中添加元素,每个新元素都从左边开始添加
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.lpush('l3',1,2)
print(r.lrange('l3',0,-1))
r.lpush('l3','88')
print(r.lrange('l3',0,-1))
#output
['2', '1']
['88', '2', '1']
```
lpushx(name,value)在列表中添加元素只有在name存在时才添加
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.lpushx('l4',1)
print(r.lrange('l4',0,-1))
r.lpush('l4',2)
r.lpushx('l4',1)
print(r.lrange('l4',0,-1))
#output:
[]
['1', '2']
```
llen(name)name对应的list元素的长度
linsert(name,where,refvalue,value)在name对应的列表的某个值前或后插入一个新值where指定前或后(befor/after)refvalue参考值即指定的元素value要插入的值
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.lpush('num','1','2')
r.linsert('num','after','2','python')#在2后面添加python元素值
r.linsert('num','before','1','redis') #在1之前插入redis
print(r.lrange('num',0,-1))
#output:
['2', 'python', 'redis', '1']
```
lset(name,index,value):对列表中的某个索引位的值修改
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
print(r.lrange('num',0,-1))
r.lset('num','0','hello')
print(r.lrange('num',0,-1))
#output
['2', 'python', 'redis', '1']
['hello', 'python', 'redis', '1']
```
lrem(name,value,num)在name对应的list中删除指定的值
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
print(r.lrange('num',0,-1))
r.lrem('num','1','2') #2为num指定的值的个数,可以指定-2从后往前删除
print(r.lrange('num',0,-1))
#output:
['1', 'hello', 'python', 'redis', '1']
['hello', 'python', 'redis']
```
lpop(name)在name对应的列表的左侧获取第一个元素并删除并返回参数的元素
lindex(name,index)在name对应的列表中根据索引获取列表元素
ltrim(name,start,end)在name对应的列表中移除start到end之间的值
lrange(name,start,end):列表分片获取数据
rpoplush(src,dst):获取源列表最后一个元素的值,并将它添加到目标列表中的最左边
blpop(keys,timeout)将多个列表排列按照从左到右去pop对应列表的元素
brpoplpush(src,dst,timeout=0):从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
##### 4set操作
sadd(name,values):添加元素到集合
scard(name):获取集合中元素的个数
sdiff(keys,*args):在第一个集合中的元素且不在其他集合的元素的集合
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.sadd('s1',1,2,3)
r.sadd('s2',4,5,2)
r.sadd('s3',7,8,1)
print(r.sdiff('s1','s2','s3'))
#output:
{'3'}
```
sdiffstore(dest,keys,*args)在第一个keys中的集合元素且不在其他集合中的元素添加到dest新集合中
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
# r.sadd('s1',1,2,3)
# r.sadd('s2',4,5,2)
# r.sadd('s3',7,8,1)
print(r.sdiffstore('s4','s1','s2','s3'))
print(r.smembers('s4'))
```
sinter(keys,*args):获取多个集合的并集
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.sadd('s1',1,2,3)
r.sadd('s2',4,5,2)
print(r.sinter('s1','s2'))
#output
{'2'}
```
sinterstore(dest,keys,*args)获取多个集合的并集并将结果加入到dest集合中
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.sadd('sex1',1,2,3,4)
r.sadd('sex2',4,5,2,7)
r.sadd('sex3',7,8,1,4,2)
r.sinterstore('sex4','sex1','sex2','sex3')
print(r.smembers('sex4'))
#output
{'4', '2'}
```
sismember(name,value)检查value是否在集合中
```python
import redis
r = redis.Redis(host='127.0.0.1',port=6379,decode_responses=True)
r.sadd('sex3',7,8,1,4,2)
print(r.sismember('sex3','8'))
#output
True
```
smembers(name):获取集合的所有成员
smove(src,dst,value):将源集合中的某个成员移动到目标集合中
spop(name):从集合的右侧(尾部)移除一个成员,并将其返回
srandmember(name,numbers)从name对应的集合中随机获取 numbers 个元素
srem(name,values)在name对应的集合中删除某些值
sunion(keys,*args):并集显示多个集合元素
sunionstore(dest,keys,*args)获取多一个name对应的集合的并集并将结果保存到dest对应的集合中
sscan(name,cursor=0,match=None,count=None):同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
sscan_iter(name,match=None,count=None):同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
##### 5有序集合操作
在集合的基础上,为每个元素排序,元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
- zadd(name,*args,**kwargs)在name对应的有序集合中添加元素
- zcard(name)获取name对应的有序集合元素的数量
- zcount(name,min,max)获取name对应的有序集合中分数 在 [min,max] 之间的个数
- zincrby(name,value,amount)自增name对应的有序集合的 name 对应的分数
- r.zrange(name, start, end, desc=False, withscores=Flase, score_cast_func=float)按照索引范围获取name对应的有序集合的元素
- zrank(name, value):获取某个值在 name对应的有序集合中的排行从 0 开始)
- zrangebylex(name, min, max, start=None, num=None):当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的 值
- zrem(name, values)删除name对应的有序集合中值是values的成员
- zremrangebyrank(name, min, max) 根据排行范围删除
- zremrangebyscore(name, min, max):根据分数范围删除
- zremrangebylex(name, min, max):根据值返回删除
- zscore(name, values)获取name对应有序集合中 value 对应的分数
- zinterstore(dest, keys, aggregate=None)获取两个有序集合的交集如果遇到相同值不同分数则按照aggregate进行操作
- zunionstore(dest, keys, aggregate=None)获取两个有序集合的并集如果遇到相同值不同分数则按照aggregate进行操作
- zscan(name, cursor=0, match=None, count=None, score_cast_func=float)同字符串相似相较于字符串新增score_cast_func用来对分数进行操作
- zscan_iter(name, match=None, count=None,score_cast_func=float)同字符串相似相较于字符串新增score_cast_func用来对分数进行操作
##### 6其他操作
- delete(*name)根据删除redis中的任意数据类型
- exists(name)检测redis的name是否存在
- keys(pattern='*')根据模型获取redis的name
- expire(name,time)为某个redis的某个name设置超时时间
- rename(src, dst)对redis的name重命名为
- move(name,db)将redis的某个值移动到指定的db下
- randomkey()随机获取一个redis的name不删除
- type(name)获取name对应值的类型
- scan(cursor=0,match=None,count=None)同字符串操作用于增量迭代获取key
- scan_iter(match=None,count=None)同字符串操作用于增量迭代获取key
#### 8、python对redis管道操作
redis默认在执行每次请求都会创建连接池申请链接和断开归还连接池一次连接操作如果想要再一次请求中指定多个命令则可以使用pipline实现一次请求指定多个命令并且默认情况下一次pipline是原子性操作。
```python
import redis
pool = redis.ConnectionPool(host='0.0.0.0', port=6379)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
r.set('name', 'python')
r.set('age', '18')
pipe.execute()
```