Python菜鸟编程第二十一课之Redis

Python菜鸟编程第二十一课之python操作redis

1. 简介

Redis是一个速度非常快的非关系数据库(non-relational database),它可以存储键(key)与5种不同类型的值(value)之间的映射(mapping),可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展写性能。

5种不同类型的值包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)

Redis 没有表结构,没有sql语句,没什么字段,速度比关系型数据库快,redis数据是存在内存上的,redis本身性能非常好,每秒支持30万次读写。缺点是没有办法持久化(重启redis可以备份数据到磁盘里面,启动的时候再次读取磁盘的数据到内存,这种方法可以实现持久化)

1.1 特点

  • Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

1.2 优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

2. Python操作Redis

2.1普通连接

redis-py提供两个类Redis和StrictRedis用于实现Redis的命令

StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令
Redis是StrictRedis的子类

demo:

redis_conn = redis.Redis(host='localhost', port=6379)  # host是redis主机,默认端口是6379
redis_conn.set('test_key', 'test_value') # 将键值对存入redis缓存,前者为key,后者为
print(redis_conn.get('test_key'))  # 取出键name对应的值
print(type(redis_conn.get('test_key')))
运行结果:
b'test_value'
<class 'bytes'>

可以看到,默认存入redis中的数据都是字节型的。我们可以在代码中加入使其变成str类型。

demo:

redis_conn = redis.Redis(host='localhost', port=6379,decode_responses=True)
redis_conn.set('test_key', 'test_value')
print(redis_conn.get('test_key'))
print(type(redis_conn.get('test_key')))
运行结果:
test_value
<class 'str'>

2.2连接池连接

redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认每个Redis实例都会维护一个自己的连接池。所以可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。

demo:

import redis
pool = redis.ConnectionPool(host='localhost', port=6379,decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('key', 'value')     # key是"key" value是"value" 将键值对存入redis缓存
print(r.get('key'))
运行结果:
value

2.3 管道

管道(pipeline)是redis在提供单个请求中缓冲多条服务器命令的基类的子类。它通过减少服务器-客户端之间反复的TCP数据库包,从而大大提高了执行批量命令的功能。在python中的redis默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。

所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。

demo:

#pipeline不仅仅用来批量的提交命令,还用来实现事务transation。默认transaction=True
import redis, time
pool = redis.ConnectionPool(host='localhost', port=6379)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)# 默认的情况下,管道里执行的命令可以保证执行的原子性,执行pipe = r.pipeline(transaction=False)可以禁用这一特性。
# 这样的效果是name和role是一起最后执行的
pipe = r.pipeline()
pipe.set('k1','v1')
time.sleep(2)
pipe.set('k2', 'v2')
pipe.execute()

3.字符串相关操作

  • set(name,value,ex=None,px=None,nx=False,xx=False):设置键值

    • name:键
    • value:值
    • ex:过期时间(秒)
    • px:过期时间(毫秒)
    • nx:True时,name不存在才会执行set操作
    • xx:True时,name存在才会执行set操作
  • get(name):获取键值

    • name:键
  • setnx(name,value):设置键值(name不存在则设置,否则不做操作)

    • name:键
    • value:值
  • setex(name,value,time):设置键值(name存在会覆盖)

    • name:键
    • value:值
    • time:过期时间(秒)
  • psetex(name,time_ms,value):设置键值(name存在会覆盖)

    • name:键
    • time_ms:过期时间(毫秒)
    • value:值
  • mset(args,kwargs):批量设置键值

  • mget(keys,args):批量获取键值

    • keys:键列表
    • args:键元组
  • getset(name,value):获取旧值并设置新值

    • name:键
    • value:新值
  • setrange(name,offset,value):修改键值

    • name:键
    • offset:起始位置(从此位置开始修改),若name不存在,且offset>0,则在前面补上offset个0x00,再加上value,为name的新值
    • value:值
  • getrange(name,start,end):获取值并截取

    • name:键
    • start:起始位置(字节),包含起始位置
    • end:结束位置(字节),包含结束位置
  • setbit(name,offset,value):对name对应的值的二进制位进行操作

    setbit函数的功能是对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。

  • getbit(name,offset):对name对应的值的二进制位进行操作

  • strlen(name):获取name对应值的长度

    • name:键
  • incr(name,amount):name不存在,则name=amount,name存在,则name对应的值+amount

    • name:键
    • amount:自增值
  • decr(name,amount):name不存在,则name=amount,name存在,则name对应的值-amount

    • name:键
    • amount:自减值
  • append(key,value):在key对应的值后面追加value

    • name:键
    • value:追加的值
  • hset(name,key,value):存储字典

    • name:键
    • key:字典的key
    • value:字典的值
  • hget(name,key):获取name对应的字典中对应key的值

    • name:键
    • key:字典的key
  • hmset(name,mapping):存储字典

    • name:键 不能是数字 包括‘1’
    • mapping:字典,如:{“info”:”shenzhen”,”age”:18}
  • hmget(name,keys,args)**:获取字典的值

    • name:键 不能是数字 包括‘1’
    • keys:字典键,如:hmget(“name”,[“info”,”age”])
    • args:字典键,如:hmget(“name”,”info”,”age”)
  • hgetall(name):获取字典(dict格式)

    • name:键
  • hlen(name):获取字典的长度

    • name:键
  • hkeys(name):获取字典的所有key

    • name:键
  • hvals(name):获取字典的所有value

    • name:键
  • hexists(name,key):name对应的字典中是否存在键key

    • name:键
    • key:字典的key
  • hdel(name,args):删除name对应的字典中的键值对

    • name:键
    • args:字典的key元组
  • hincrby(name,key,amount):name对应的字典中,若key存在,则key对应的值+amount,否则key=amount

    • name:键
    • key:字典中key
    • amount:自增值(整数)
  • hincrbyfloat(name,key,amount):name对应的字典中,若key存在,则key对应的值+amount,否则key=amount

    • name:键
    • key:字典中key
    • amount:自增值(浮点数)
  • hscan(name,cursor=0,match=None,count=None):迭代式获取,对于数据大的数据非常有用,hscan可以实现分片式获取,避免一次性获取完毕,将内存撑爆

    • name:键
    • cursor:游标
    • match:匹配的key,默认None,表示所有的key
    • count:每次分片最少获取个数,默认None表示采用Redis默认分片个数
# 第一次
cursor1,data = r.hscan("province",cursor=0)
# 第二次
cursor2,data = r.hscan("province",cursor=cursor1)
...
依次迭代,当返回的游标值为0时表示全部获取完毕,值得注意的是只有当"province"对应的字典中含有大量数据时,redis才会有采取分片操作(大概在513条数据左右)
  • hscan_iter(name,match,count):利用yield封装hscan创建生成器,实现分批去redis中获取数据
    • name:键
    • match:匹配的key,默认None,表示所有的key
    • count:每次分片最少获取个数,默认None表示采用Redis默认分片个数

4.列表相关操作

  • *lpush(name,value)**:存储列表(往前(左)插入)
    • name:键
    • value:值,格式:11,22,33。值越后,在列表中存储的位置越前
  • *rpush(name,value)**:存储列表(往后(右)插入)
    • name:键
    • value:值,格式:11,22,33。值越后,在列表中存储的位置越后
  • lpushx(name,value):在name对应的list中添加元素,name不存在不操作
    • name:键
    • value:值。值添加到列表的最前面
  • llen(name):获取name对应的list的长度
    • name:键
  • linsert(name,where,refvalue,value):在name对应的list中refvalue的前后插入value
    • name:键
    • where:before或after
    • refvalue:list中的某个值,与where配合确定位置后插入value
    • value:插入的值
  • lset(name,index,value):修改name对应的list中指定位置的值
    • name:键
    • index:索引位置
    • value:值
  • lrem(name, count, value):删除name对应的list中的指定值
    • name:键
    • count:0:删除所有配到的指定值;count为正数时:从匹配到该值的位置时,删除count个;count为负数时:从后往前匹配,从匹配到该值的位置时,删除count个
    • value:删除的指定值
  • lpop(name):删除name对应的list中的第一个值
    • name:键
  • lindex(name,index):获取name对应的list中指定位置的值
    • index:索引位置
  • lrange(name,start,end):获取name对应的list中切片后的值
    • name:键
    • start:起始位置(包括)
    • end:结束位置(包括)
  • ltrim(name,start,end):移除name对应的list中,不在start-end之间的值
    • name:键
    • start:起始位置(包括)
    • end:结束位置(包括)
  • rpoplpush(src,dst):移除src对应的list中最右边(即最后)的元素,并将其加到dst中对应list的最左边(即最前)
    • src:键
    • dst:键
  • brpoplpush(src,dst,timeout=0):移除src对应的list中最右边(即最后的元素),并将其加到dst中对应list的最左边(即最前)
    • src:键
    • dst:键
    • timeout:当src没有值,阻塞!阻塞时间

5.集合相关操作

  • sadd(name,value):添加集合
    • name:键
    • value:值
  • scard(name):获取集合元素的个数
    • name:键
  • *sdiff(keys,args)**:获取多个集合的差集
    • kyes:键
    • args:键
  • *sdiffstore(dest,keys,args)**:获取keys对应集合,与args中多个集合的差集,并将其设置为dest对应的集合
    • dest:键
    • keys:键
    • args:键,若args为空,dest对应的集合则为keys对应的集合
  • *sinter(keys,args)**:获取多个集合的交集
    • keys:键
    • args:键
  • sinterstore(dest,keys,args):获取keys对应集合,与args中多个集合的交集,并将其设置为dest对应的集合
    • dest:键
    • keys:键
    • args:键,若args为空,dest对应的集合则为keys对应的集合
  • sismember(name,value):判断value是否name对应集合中的成员
    • name:键
    • value:值
  • smembers(name):获取name对应的集合
    • name:键
  • smove(src,dst,value):将src中对应集合中的value移动到dst对应的集合的最左边(即最前面)
    • src:键
    • dst:键
    • value:值
  • spop(name):移除name对应集合中最右边(即最后面)的元素
    • name:键
  • srandmember(name,number=None):获取name对应集合中随机元素
    • name:键
    • number:获取number个元素,默认取一个元素
  • *srem(name,values)**:删除name对应集合中的某些元素
    • name:键
    • values:值
  • *sunion(keys,args)**:获取多个集合的并集
    • keys:键
    • args:键

6.有序集合相关操作

  • *zadd(name,args,kwargs):在name对应的有序集合中添加元素,分数越小,越靠前
    • name:键
    • args:键值对,例如:’n1’,1,’n2’,2
    • kwargs:键值对,例如:’n1’=1,’n2’=2
  • zcard(name):获取name对应的有序集合的元素个数
    • name:键
  • zcount(name,min,max):获取name对应的有序集合中,min<=分数<=max中的元素个数
    • name:键
    • min:小值(分数)
    • max:大值(分数)
  • zincrby(name,value,amount):自增name对应的有序集合中,value对应的分数+amount,若value不存在,则插入value=amount
    • name:键
    • value:值
    • amount:分数自增值
  • zrange(name,start,end,desc=False,withscores=False,score_with_func=float):获取name对应的有序集合中,start<=下标<=end的所有数据。
    • name:键
    • start:起始位置
    • end:结束位置
    • desc:是否是倒序,默认False
    • withscores:是否获取分数,默认False
    • score_with_func:分数类型
  • zrank(name,value):获取value在name对应的有序集合中的下标
    • name:键
    • value:值
  • *zrem(name,values)**:删除在name对应的有序集合中value对应的分数
    • name:键
    • values:值,如:values=”n1”,”n2”
  • zremrangebyrank(name,min,max):删除在name对应的有序集合中,min<=下标<=max的数据
    • name:键
    • min:小(下标)
    • max:大(下标)
  • zremrangebyscore(name,min,max):删除在name对应的有序集合中,min<=分数<=max的数据
    • name:键
    • min:小(分数)
    • max:大(分数)
  • zscore(name,value):获取name对应的有序集合中value对应的分数
    • name:键
    • value:值
  • zinterstore(name,keys,aggregate=None):获取name对应的有序集合的交集,并使name指向这个交集
    • name:键
    • keys:多个有序集合的键的元组,例:keys=(“zlist1”,”zlist2”)
    • aggregate:聚合操作,值可以是:”MAX”,”MIN”,”SUM”,当遇到值相同,分数不同时,可以对分数做操作:取大值、取小值或取和值
  • zunionstore(name,keys,aggregate=None):获取name对应的有序集合的并集,并使name指向这个并集
    • name:键
    • keys:多个有序集合的键的元组,例:keys=(“zlist1”,”zlist2”)
    • aggregate:聚合操作,值可以是:”MAX”,”MIN”,”SUM”,当遇到值相同,分数不同时,可以对分数做操作:取大值、取小值或取和值

7.其他相关操作

  • *delete(names)**:删除Redis中的任意数据类型
    • names:键
  • exists(name):判断键是否存在
    • name:键
  • *keys(pattern=””)**:获取符合规则的所有键
    • pattern:通配符,默认获取所有。常见:”h”:h结尾的键;”h”:h开头的键;”hx”:h开头,x结尾的键;”h[ae]x”:获取名为hax或hex的键
  • expaire(name,time):设置超时时间
    • name:键
  • rename(src,dst):修改键名
    • src:旧键名
    • dst:新键名
  • move(name,db):将键移动至其他db
    • name:键
    • db:db序号
  • randomkey():随机获取key
  • type(name):获取键对应的数据类型
    • name:键
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值