三、python进阶(17)- Redis操作

一、基本介绍

  1、简介

    Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis全称为:Remote Dictionary Server,该软件使用C语言编写,Redis是一个key-value存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。

    Redis特点:
      Redis以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。 

    Redis应用场景:
      因为Redis交换数据快,所以在服务器中常用来存储一些需要频繁调取的数据,这样可以大大节省系统直接读取磁盘来获得数据的I/O开销,更重要的是可以极大提升速度。将这种热点数据存到Redis(内存)中,要用的时候,直接从内存取,极大的提高了速度和节约了服务器的开销。

二、redis基础

  1、redis五种数据类型

string` 字符串
list 列表
hash 哈希
set 集合
sorted sets 有序集合

    key 有5中数据类型:string、list、set、zset(sorted set)、hash。

    value :都是字符串类型的

    redis 里面所有的 value。 都是字符串类型的

  2、String操作

操作 代码 例子
设置 set key value set name 'jianeng'
获取 get key get name
查看过期时间 ttl key ttl name    -1 表示永久     -2 表示 不存在
设置过期时间

1. 给已经存在 key,设置过期时间

     expire key seconds 

2. 设置 key的同时,设置过期时间

  set key value ex seconds

   setex key seconds value

1. expire name 20  

2. set age 18 ex 20 

2.setex sex 20 '男' 

追加

给已有的value,再添加新的值

append key value

append name love
设置/获取多个

1. 设置多个string

        mset key value  key value.. 

2. 获取多个

        mget key key key ... 

1.mset username 'jianeng' password '123'

2.mget username password name

key 操作  查看所有的keykeys *,keys n*  
删除  del key  del name
查看key是否存在  exists key  exists name 存在返回 1,不存在返回 0
查看key类型  type key  type name

  

  3、运算

操作 代码 例子
设置键为整数 set key num  set num 1  自动识别,字符串里面的 整数
加1 incr key incr num
减1 decr key decr num
加整数 incrby key increment incrby num 50
减整数 decrby key increment decrby num 50

  4、List操作

 操作  代码  例子
 设置

1. lpush  左添加  (栈)

  lpush  key  value

2. rpush  右添加   (队列)

  rpush  key  value

1.lpush my_list a b c d

2.rpush my_rlist a b c d

查看  lrange  key  start  stop 查看所有

  lrange my_list 0 -1

 获得list的元素个数  llen key  llen  my_list
 查看位于lindex 位置上的元素  lindex key  index  lindex my_list  3
 删除

 1. 删除左边第一个

  lpop key

2. 删除右边第一个

  rpop key

3. 删除指定数量的值

  lrem  key count  value

先添加数据 rpush  test_list  a a b b c d e a d f m c

1. lpop  my_rlist

2. rpop  my_list

3.a. count > 0 从左往右 删除数量为count的value

  lrem test_list 2 a

 b. count = 0 删除所有的 value

  lrem test_list 0 a

 c. count < 0 从右往左 删除数量为count的value

  lrem test_list -1 b

   

 

 5、hash操作

  redis中的Hash 在内存中类似于一个name对应一个dic来存储 

设置 hset key field value

#  user { name:jianeng}
hset user name jianeng

获取 hget key field hget user name
删除 hdel key field hdel user name
设置多个 hmset key field value [field value]

# user{name:jianeng , age:18, sex:male }

hmset user name jianeng age 18 sex male

获取多个 hmget key field field

# itmes

hmget user name age

获取全部`field value` hgetall key  hgetall user
获取所有的`field` hkeys key

# keys

hkeys user

获取所有的`value` hvals key

# values

hvals user

获取`field`的个数 hlen key hlen user

    

 6、set集合操作

设置 sadd key value [value]    (唯一,无序) sadd my_set m n b v c x z b
获取 smembers key smembers my_set
删除

1. 指定删除

  srem key member

2. 随机删除

  spop  key

1. srem my_set c

2. spop my_set

移动一个集合的值到另一个集合 smove oldkey newkey member

smove my_set my_set2 z

判断集合存在某个值 sismember key value sismember my_set2 b
交集

1.sinter key1 key2 ..

2. 把 key1 key2的交集合并到`newkey`

  sinterstore newkey key1 key2

1. sinter my_set my_set2

2. sinterstore  new_set my_set my_set2

并集

1. sunion key1 key2 ...

2. 把 key1 key2的并集合并到`newkey`

  sunionstore newkey key1 key2

1. sunion my_set my_set2

2. sunionstore new_set2 my_set my_set2

差集

1. sdiff key1 key2

2. 把 key1 key2的差集合并到`newkey`

  sdiffstore newkey key1 key2

1. sdiff my_set my_set2

2. sdiffstore new_set3 my_set my_set2

获取集合个数 scard key scard my_set
随机返回一个 srandmember key srandmember my_set

 

 7、zset 有序集合操作

  有序集合:

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

设置 zadd key score member

zadd my_zset 1 'one'
zadd my_zset 2 'two'
zadd my_zset 3 'three'

获取

1. `zrange`正序

  zrange key start stop    (withscores)

2.  `zrevrange`倒序

  zrevrange key start stop

1. zrange my_zset 0 -1  withscores

2. zrevrange my_zset 0 -1  withscores

 删除  zrem key member  zrem my_zset two
 索引

 1. zrank正序

  zrank key member

2. zrevrank反序

  zrevrank key member

1. zrank my_zset three

2. zrevrank my_zset three

 查看有序集合元素数  zcard key  zcard my_zset
 返回集合中 score 在给定区间的元素  zrange key min max withscores

返回了 score 在 2~3 区间的元素

  zrangebyscore my_zset 2 3 withscores

返回了 score 在 整个区间的元素

  zrange my_zset 0 -1 withscores

 返回集合中 score 在给定区间的数量  zcount key min max  zcount my_zset 2 3
 查看score值  zscore key member  zscore my_zset two
 删除集合中排名在给定区间的元素(正向)  zrange key min max withscores

 zrange my_zset 0 -1 withscores

 zremrangebyrank my_zset 1 3

 删除集合中 score 在给定区间的元素  zrange key min max withscores  zremrangebyscore my_zset 3 5

三、Redis发布和订阅

  首先定义一个RedisHelper类,连接Redis,定义频道为monitor,定义发布(publish)及订阅(subscribe)方法。

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import redis

class RedisHelper(object):
    def __init__(self):
        self.__conn = redis.Redis(host='192.168.0.110',port=6379)#连接Redis
        self.channel = 'monitor' #定义名称

    def publish(self,msg):#定义发布方法
        self.__conn.publish(self.channel,msg)
        return True

    def subscribe(self):#定义订阅方法
        pub = self.__conn.pubsub()
        pub.subscribe(self.channel)
        pub.parse_response()
        return pub

  1. 发布
    publish 频道 消息

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#发布
from RedisHelper import RedisHelper

obj = RedisHelper()
obj.publish('hello')#发布

  2. 订阅
    subscribe 频道

      首先定义一个RedisHelper类,连接Redis,定义频道为monitor,定义发布(publish)及订阅(subscribe)方法。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#订阅
from RedisHelper import RedisHelper

obj = RedisHelper()
redis_sub = obj.subscribe()#调用订阅方法

while True:
    msg= redis_sub.parse_response()
    print (msg) 

四、python实现代码

  1、连接

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import redis

r = redis.Redis(host='192.168.0.110', port=6379,db=0)
r.set('name', 'zhangsan')   #添加
print (r.get('name'))   #获取

   2、连接池

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

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import redis

pool = redis.ConnectionPool(host='192.168.0.110', port=6379)
r = redis.Redis(connection_pool=pool)
r.set('name', 'zhangsan')   #添加
print (r.get('name'))   #获取

     3、管道

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

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import redis
pool = redis.ConnectionPool(host='192.168.0.110', port=6379)
r = redis.Redis(connection_pool=pool)

pipe = r.pipeline(transaction=True)

r.set('name', 'zhangsan')
r.set('name', 'lisi')

pipe.execute()

五、python操作redis方法

  1、常用操作

常用操作
方法 功能
delete(*names)
#根据name删除redis中的任意数据类型
exists(name)
#检测redis的name是否存在
keys(pattern='*')
#根据* ?等通配符匹配获取redis的name
expire(name ,time)
# 为某个name设置超时时间
rename(src, dst)
# 重命名
move(name, db))
# 将redis的某个值移动到指定的db下
randomkey()
#随机获取一个redis的name(不删除)
type(name)
# 获取name对应值的类型

  

   2、String

 方法  功能  例子
set(key, value)

   #在Redis中设置值,默认不存在则创建,存在则修改
set('name', 'zhangsan')
'''参数:
     set(name, value, ex=None, px=None, nx=False, xx=False)
     ex,过期时间(秒)
     px,过期时间(毫秒)
     nx,如果设置为True,则只有name不存在时,当前set操作才执行,同setnx(name, value)
     xx,如果设置为True,则只有name存在时,当前set操作才执行'''
setex(name, value, time)
#设置过期时间(秒)
 
psetex(name, time_ms, value)
#设置过期时间(豪秒)
 
 mset(key=value)
#批量设置值
r.mset(name1='zhangsan', name2='lisi')
#或
r.mget({"name1":'zhangsan', "name2":'lisi'})
 get(name)    #获取值  
mget(keys, *args)    #批量获取值
#批量获取
print(r.mget("name1","name2"))
#或
li=["name1","name2"]
print(r.mget(li))
getset(name, value)
#设置新值,打印原值
print(r.getset("name1","wangwu")) #输出:zhangsan
print(r.get("name1")) #输出:wangwu
getrange(key, start, end)
#根据字节获取子序列
r.set("name","zhangsan")
print(r.getrange("name",0,3))#输出:zhan
setrange(name, offset, value)
#修改字符串内容,从指定字符串索引开始向后替换,如果新值太长时,则向后添加
r.set("name","zhangsan")
r.setrange("name",1,"z")
print(r.get("name")) #输出:zzangsan
r.setrange("name",6,"zzzzzzz")
print(r.get("name")) #输出:zzangszzzzzzz
setbit(name, offset, value)
#对二进制表示位进行操作
#对二进制表示位进行操作
''' name:redis的name
    offset,位的索引(将值对应的ASCII码变换成二进制后再进行索引)
    value,值只能是 1 或 0 '''
str="345"
r.set("name",str)
for i in str:
    print(i,ord(i),bin(ord(i)))#输出 值、ASCII码中对应的值、对应值转换的二进制
'''
输出:
    3 51 0b110011
    4 52 0b110100
    5 53 0b110101'''
r.setbit("name",6,0)#把第7位改为0,也就是3对应的变成了0b110001
print(r.get("name"))#输出:145
getbit(name, offset)
#获取name对应值的二进制中某位的值(0或1)
r.set("name","3") # 对应的二进制0b110011
print(r.getbit("name",5))   #输出:0
print(r.getbit("name",6))   #输出:1
bitcount(key, start=None, end=None)
#获取对应二进制中1的个数
r.set("name","345")#0b110011 0b110100 0b110101
print(r.bitcount("name",start=0,end=1)) #输出:7
''' key:Redis的name
    start:字节起始位置
    end:字节结束位置'''
strlen(name)
#返回name对应值的字节长度(一个汉字3个字节)
r.set("name","zhangsan")
print(r.strlen("name")) #输出:8
incr(self, name, amount=1)
#自增mount对应的值,当mount不存在时,则创建mount=amount,否则,则自增,amount为自增数(整数)
print(r.incr("mount",amount=2))#输出:2
print(r.incr("mount"))#输出:3
print(r.incr("mount",amount=3))#输出:6
print(r.incr("mount",amount=6))#输出:12
print(r.get("mount")) #输出:12
incrbyfloat(self, name, amount=1.0)
#类似 incr() 自增,amount为自增数(浮点数)
 
decr(self, name, amount=1)
#自减name对应的值,当name不存在时,则创建name=amount,否则,则自减,amount为自增数(整数)
 
append(name, value)
#在name对应的值后面追加内容
 r.set("name","zhangsan")
print(r.get("name"))    #输出:'zhangsan
r.append("name","lisi")
print(r.get("name"))    #输出:zhangsanlisi

 3、list

方法
功能
例子
lpush(name,values)
# 在name对应的list中添加元素,每个新的元素都添加到列表的最左边
r.lpush("list_name",2)
r.lpush("list_name",3,4,5)#保存在列表中的顺序为5,4,3,2
rpush(name,values)
#同lpush,但每个新的元素都添加到列表的最右边
 
lpushx(name,value)
#在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
 
rpushx(name,value)
#在name对应的list中添加元素,只有name已经存在时,值添加到列表的最右边
 
llen(name)
# name对应的list元素的个数
 print(r.llen("list_name"))
linsert(name, where, refvalue, value))

  # 在name对应的列表的某一个值前或后插入一个新值

r.linsert("list_name","BEFORE","2","SS")#在列表内找到第一个元素2,在它前面插入SS

'''参数:
name: redis的name
where: BEFORE(前)或AFTER(后)
refvalue: 列表内的值
value: 要插入的数据'''

r.lset(name, index, value)
#对list中的某一个索引位置重新赋值
 r.lset("list_name",0,"bbb")
r.lrem(name, value, num)

   #删除name对应的list中的指定值

 r.lrem("list_name","SS",num=0)

''' 参数:
name: redis的name
value: 要删除的值
num: num=0 删除列表中所有的指定值;
num=2 从前到后,删除2个;
num=-2 从后向前,删除2个'''

lpop(name)
#移除列表的左侧第一个元素,返回值则是第一个元素
 print(r.lpop("list_name"))
lindex(name, index)
#根据索引获取列表内元素
 print(r.lindex("list_name",1))
lrange(name, start, end)
#分片获取元素
 print(r.lrange("list_name",0,-1))
ltrim(name, start, end)
#移除列表内没有在该索引之内的值
 r.ltrim("list_name",0,2)
rpoplpush(src, dst)
# 从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
 #src 要取数据的列表    #dst 要添加数据的列表
brpoplpush(src, dst, timeout=0)
#同rpoplpush,多了个timeout, 
timeout:取数据的列表没元素后的阻塞时间,0为一直阻塞
 r.brpoplpush("list_name","list_name1",timeout=0)
blpop(keys, timeout)
#将多个列表排列,按照从左到右去移除各个列表内的元素
 r.lpush("list_name",3,4,5)
r.lpush("list_name1",3,4,5)
while True:
    print(r.blpop(["list_name","list_name1"],timeout=0))
    print(r.lrange("list_name",0,-1),r.lrange("list_name1",0,-1)
'''keys: redis的name的集合
   timeout: 超时时间,获取完所有列表的元素之后,
阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞'''
r.brpop(keys, timeout)
#同blpop,将多个列表排列,按照从右像左去移除各个列表内的元素
 

 4、hash

方法 功能 例子
 hset(name, key, value)
#name对应的hash中设置一个键值对(不存在,则创建,否则,修改)
r.hset("dic_name","a1","aa")
hget(name,key)
#在name对应的hash中根据key获取value
r.hset("dic_name","a1","aa")
#在name对应的hash中根据key获取value
print(r.hget("dic_name","a1"))#输出:aa
hgetall(name)
#获取name对应hash的所有键值
print(r.hgetall("dic_name"))
hmset(name, mapping)
#在name对应的hash中批量设置键值对,mapping:字典
dic={"a1":"aa","b1":"bb"}
r.hmset("dic_name",dic)
print(r.hget("dic_name","b1"))#输出:bb
hmget(name, keys, *args)
# 在name对应的hash中获取多个key的值
li=["a1","b1"]
print(r.hmget("dic_name",li))
print(r.hmget("dic_name","a1","b1"))
hlen(name)、hkeys(name)、hvals(name)  
dic={"a1":"aa","b1":"bb"}
r.hmset("dic_name",dic)

#hlen(name) 获取hash中键值对的个数
print(r.hlen("dic_name"))

#hkeys(name) 获取hash中所有的key的值
print(r.hkeys("dic_name"))

#hvals(name) 获取hash中所有的value的值
print(r.hvals("dic_name"))
hexists(name, key)
#检查name对应的hash是否存在当前传入的key
print(r.hexists("dic_name","a1"))#输出:True
hdel(name,*keys)
#删除指定name对应的key所在的键值对
r.hdel("dic_name","a1")
hincrby(name, key, amount=1)
#自增hash中key对应的值,不存在则创建key=amount(amount为整数)
print(r.hincrby("demo","a",amount=2))
hincrbyfloat(name, key, amount=1.0)
#自增hash中key对应的值,不存在则创建key=amount(amount为浮点数)
 
hscan(name, cursor=0, match=None, count=None)    
hscan_iter(name, match=None, count=None)    

 5、set

方法 功能 例子
sadd(name,values)
#给name对应的集合中添加元素

 r.sadd("set_name","aa")

 r.sadd("set_name","aa","bb")

 smembers(name)  
#获取name对应的集合的所有成员
 
 scard(name)  
#获取name对应的集合中的元素个数
 
r.scard("set_name")
 sdiff(keys, *args)  
#在第一个name对应的集合中且不在其他name对应的集合的元素集合
r.sadd("set_name","aa","bb")
r.sadd("set_name1","bb","cc")
r.sadd("set_name2","bb","cc","dd")
print(r.sdiff("set_name","set_name1","set_name2"))#输出:{aa}
 sdiffstore(dest, keys, *args)  
#相当于把sdiff获取的值加入到dest对应的集合中
 
 sinter(keys, *args)  
# 获取多个name对应集合的并集
 
r.sadd("set_name","aa","bb")
r.sadd("set_name1","bb","cc")
r.sadd("set_name2","bb","cc","dd")

print(r.sinter("set_name","set_name1","set_name2"))#输出:{bb}
 sinterstore(dest, keys, *args)  
#获取多个name对应集合的并集,再讲其加入到dest对应的集合中
 
 sismember(name, value)  
#检查value是否是name对应的集合内的元素
 
 smove(src, dst, value)  
#将某个元素从一个集合中移动到另外一个集合
 
 spop(name)  
#从集合的右侧移除一个元素,并将其返回
 
 srandmember(name, numbers)  
# 从name对应的集合中随机获取numbers个元素
 
print(r.srandmember("set_name2",2))
 srem(name, values)  
#删除name对应的集合中的某些值
 
print(r.srem("set_name2","bb","dd"))
 sunion(keys, *args)  
#获取多个name对应的集合的并集
 
r.sunion("set_name","set_name1","set_name2")
 sunionstore(dest,keys, *args)  
#获取多个name对应的集合的并集,并将结果保存到dest对应的集合中
 

 6、zset

方法 功能 例子
zadd(name, *args, **kwargs)
# 在name对应的有序集合中添加元素
r.zadd("zset_name", "a1", 6, "a2", 2,"a3",5)
#或
r.zadd('zset_name1', b1=10, b2=5)
zcard(name)
#获取有序集合内元素的数量
 
zcount(name, min, max)
#获取有序集合中分数在[min,max]之间的个数
print(r.zcount("zset_name",1,5))
zincrby(name, value, amount)
#自增有序集合内value对应的分数
r.zincrby("zset_name","a1",amount=2)#自增zset_name对应的有序集合里a1对应的分数
zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
# 按照索引范围获取name对应的有序集合的元素
aa=r.zrange("zset_name",0,1,desc=False,withscores=True,score_cast_func=int)
print(aa)
'''参数:
    name    redis的name
    start   有序集合索引起始位置
    end     有序集合索引结束位置
    desc    排序规则,默认按照分数从小到大排序
    withscores  是否获取元素的分数,默认只获取元素的值
    score_cast_func 对分数进行数据转换的函数'''
zrevrange(name, start, end, withscores=False, score_cast_func=float)
#同zrange,集合是从大到小排序的
 
zrank(name, value)、zrevrank(name, value)
#获取value值在name对应的有序集合中的排行位置(从0开始)
print(r.zrank("zset_name", "a2"))

print(r.zrevrank("zset_name", "a2"))#从大到小排序
zscore(name, value)
#获取name对应有序集合中 value 对应的分数
print(r.zscore("zset_name","a1"))
zrem(name, values)
#删除name对应的有序集合中值是values的成员
r.zrem("zset_name","a1","a2")
zremrangebyrank(name, min, max)
#根据排行范围删除
 
zremrangebyscore(name, min, max)
#根据分数范围删除
 
zinterstore(dest, keys, aggregate=None)    r.zadd("zset_name", "a1", 6, "a2", 2,"a3",5)
r.zadd('zset_name1', a1=7,b1=10, b2=5)
# 获取两个有序集合的交集并放入dest集合,如果遇到相同值不同分数,则按照aggregate进行操作
# aggregate的值为: SUM  MIN  MAX
r.zinterstore("zset_name2",("zset_name1","zset_name"),aggregate="MAX")
print(r.zscan("zset_name2"))
 zunionstore(dest, keys, aggregate=None)  #获取两个有序集合的并集并放入dest集合,其他同zinterstore,  

猜你喜欢

转载自www.cnblogs.com/zhiduanqingchang/p/8985265.html
今日推荐