[redis入门] redis基本命令和Python如何操做Redis | 8月更文挑战

微信公众号搜索【程序媛小庄】 - 没有白走的路,每一步都算数java

image.png

前言

安装好Redis后,一样可使用Python去操做Redis,Python操做redis是经过第三方模块的,本文介绍如何使用Python对Redis进行增删改查的操做。python

Python操做Redis

首先须要安装包:pip install redisweb

普通链接

在Python代码中进行链接:redis

from redis import Redis


# 建立链接对象
conn = Redis(host='127.0.0.1', port=6379, password='1234')  # redis默认端口是6379

# 经过链接对象设置redis缓存
ret = conn.set('name','python')
print(conn.get('name')) # zhy
复制代码

链接池

普通链接是链接一次就断了,在常用redis的场景下频繁的建立链接和释放链接很是耗费资源,所以能够采起链接池的方式,当程序建立数据源实例时,系统会一次建立多个数据库链接,并把这些数据库链接保存在链接池中,当程序须要进行数据库访问时,无需建立新的链接直接从链接池中取出一个空闲的链接对象便可。数据库

# 须要说明的是,链接池对象必须符合单例模式,单例模式有多种实现方法,这里只列举一种
import redis


class Pool:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = redis.ConnectionPool(host='127.0.0.1',port=6379,max_connections=100)
        return cls._instance
    
    
# 生成链接池对象 
pool = Pool()
# 生成链接对象
conn = redis.Redis(connection_pool=pool)
复制代码

Redis API使用

Redis中每种数据结构存储数据的方式请看下图:缓存

image.png

string类型

字符串类型是Redis中最为基础的数据存储类型,最大容量是512M,数字在存储时也是保存为字符串string。下面是string类型经常使用的方法。微信

设置值

set:默认不存在建立,存在则修改。markdown

# redis直接操做
set(name, value, ex=None, px=None, nx=False, xx=False)
参数说明:
	ex: 过时时间,单位是秒
    px: 过时时间,单位是毫秒
    nx: 若是设置为True,则只有name不存在时,当前set操做才执行,即添加
    xx: 默认是False,若是设置为True的话,表示若是name不存在,不会建立新的,若是key存在则更新redis中key对应的数据
        
# Python操做
ret = conn.set('age', 18, ex=10)
ret = conn.set('name1','python', nx=True)
ret = conn.set('name1','python', xx=True)
复制代码

setnx(name, value):用法等同于set(name, value, nx=True)数据结构

setex(name, value, time): 用法等同于set(name, value, ex=time)app

psetex(name, value, time_ms):用法等同于setex,可是时间参数单位是毫秒。

mset(kwargs):批量设置值。

# redis直接操做批量设置值
mset(k1='v1', k2='v2')
# 或者
mset({'k1': 'v1', 'k2': 'v2'})

# Python操做
ret = conn.mset({'name':'lx','name2':'doushabao','name3':'haha'})
复制代码

获取值

get(name):根据name获取值

# redis 直接操做
get(name)

# python操做
ret = conn.get('name')
复制代码

mget(keys, args):根据key批量获取值。

# redis直接操做
mget('Python', 'java')
# 或
mget(['Python', 'java'])

# python操做
ret = conn.mget('name','name1')
复制代码

getset(name, value):设置新的值并返回原来的值。

# python操做
r.set('name', 'Python')
old_name = r.getset('name', 'java')  # old_name = b'Python'
复制代码

getrange(key, start, end):根据字节获取子序列,key是redis中设置的key,start是起始位置,end是结束位置,从零开始。

# python操做
ret = conn.getrange('name',0,1)
# name对应的是java
print(ret)  # ja
复制代码

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

# Python操做
ret = conn.setrange('name',1,'iiiiiiiiiii')
复制代码

strlen(name): 返回name对应值的字节长度

# python操做
ret = conn.strlen('name')
复制代码

其余方法

incr(self, name, amount=1):同incrby,适用因而数字的字符串的加法,不然报错,自增 name对应的值,当name不存在时,则建立name=amount,不然,则自增。

decr(self, name, amount=1)):自检name对应的值,不存在则建立name=amount,不然自减。

append(key, value):在redis name对应的值后拼接新的字符串

# python操做
conn.set('name', 'hah')
conn.append('name', 'hello')
print(r.get('name'))	# b'hahahello'
复制代码

hash类型

用于存储对象,对象的结构为key-value形式,相似于Python的字典,值的类型为string,不能嵌套使用。能够存储一组关联性较强的数据。

设置值

hset(name, key=None, value=None, mapping=None):name对应的hash中设置一个键值对,不存在建立,不然进行修改操做。

# 参数说明
name,redis的name
key,name对应的hash中的key
value,name对应的hash中的value,只能是字符串 整型 浮点型 或者是bytes类型
mapping, 批处理设置键值对,py38之后批量插入使用hset,启用hmset

# Python操做
ret = conn.hset('gae','age',19)
ret = conn.hset('yyy',mapping={'x1':'o1', 'x2':'o2'}) 
复制代码

hsetnx(name, key, value):当name对应的hash中不存在当前key时则建立(至关于添加),并返回1;存在则不处理,返回0

hmset(name,mapping):在Python3.8版本中被弃用,使用hset便可。

ret = conn.hmset('xxxxx',{'k1':'v1','k2':'v2'})
复制代码

获取值

hget(name, key, value):获取name对应的hash中的key对应的value。

hmget(name, keys, args):在name对应的hash中获取多个key的值,列表的形式返回。

# 参数说明
name,reids对应的name
keys,要获取key集合,如:['k1', 'k2', 'k3']
*args,要获取的key,如:k1,k2,k3
# Python操做
ret = conn.hmget('xxxxx','k1','k2')
ret = conn.hmget('xxxxx',['k1','k2'])
复制代码

hlen(name): 获取name对应的hash中键值对的个数。

hkeys(name):获取name对应的hash中全部的key的值。

hvals(name):获取name对应的hash中全部的value的值。

hdel(name, keys):将name对应的hash中指定key的键值对删除,支持删除多个。

conn.hdel('info', 'name', 'age')
复制代码

其余操做

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

# 参数说明
    name,redis中的name
    key, hash对应的key
    amount,自增数(整数)
    
# Python操做
ret1 = conn.hincrby('xxxxx','number',6)
复制代码

hscan_iter(name, match=None, count=None):利用yield封装hscan建立生成器,实现分批去redis中获取数据

# 参数说明
match,匹配指定key,默认None 表示全部的key
count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数 

# Python使用
for item in conn.hscan_iter('xx'):
    print(item)	# 打印全部的key-value键值对

for item in conn.hscan_iter('xx', match='k1'):
    print(item)	# 打印k1这个键和其对应的值
复制代码

list类型

列表的元素类型为string,好比key: [值1, 值2...]

lpush(name, values):在name对应的链表中添加元素,每一个元素都添加到链表的最左边。

conn.lpush('l1', 1,2,3,4,5)  # l1 = [b'5', b'4', b'3', b'2', b'1']
复制代码

rpush(name, values):在name对应的链表中添加元素,每一个元素都添加到链表的最右边。

conn.rpush('l1', 6)	# [b'5', b'4', b'3', b'2', b'1', b'6']
复制代码

lpushx/rpushx(name, value):在name对应的list中添加元素,只有name已经存在时将元素插在最左边(右边);不存在不作任何操做。

llen(name):name对应的list元素的个数。

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

# 参数说明
    name,redis的name
    where,BEFORE或AFTER, 不区分大小写
    refvalue,标杆值,即:在它先后插入数据
    value,要插入的数据
    
# Python操做
conn.linsert('l1', 'after', 3, 12)  # [b'5', b'4', b'3', b'12', b'2', b'1', b'6']
复制代码

r.lset(name, index, value):对name对应的list中的某一个索引位置从新赋值。

# 参数说明
    name,redis的name
    index,list的索引位置
    value,要设置的值
    
# Python操做
r.lset('l1', 2, '99')  # [b'5', b'4', b'99', b'12', b'12', b'2', b'1', b'6']
复制代码

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

# 参数说明
name,redis的name
value,要删除的值
count,
    count=0,删除列表中全部的指定的value;
    count=2, 从前到后,删除前2个value;
    count=-2, 从后向前,删除后2个value
复制代码

lpop/rpop(name):删除name对应的列表中左边(右边)出现的第一个元素并返回。

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

lrange(name, start, end):在name对应的列表分片获取数据。

ltrim(name, start, end):在name对应的列表中移除start-end之索引外的元素,双闭区间。

blpop(name, timeout=0):弹出name对应列表中的左边第一个元素,若是不存在则阻塞,等待列表中出现元素。 timeout为等待时间,表示阻塞时等待的时间,若是timeout=0则表示无期限的原地阻塞。

blpop('lx_list1')		# 弹出lx_list1中第一个元素,若是不存在则原地阻塞
复制代码

自定制分批获取链表数据

# 每次从redis中取2个元素, 经过生成器返回出去
# 而后再次while循环,直到知足取值个数要求,
def scan_list(name,count=2):
    index = 0
    while True:
        data_list = conn.lrange(name,index,count+index)
        if not data_list:
            return        # 循环完毕,结束
        # 由于lrange是前闭后闭区间
        index += count+1  # 更新取值区间的起点
        for item in data_list:
            yield item   # 每次切片的列表经过生成器依次返回

# 使用
for i in scan_list('name',count=3):
    print(i)
复制代码

set类型

无序集合,元素为string类型,元素惟一不重复。与Python中集合的概念一致。

sadd(name, values):name对应的集合中添加元素。

conn.sadd('num1', 1,2,3,4,5) # num1 = {b'4', b'1', b'2',b'3', b'5'} 无序的
复制代码

scard(name):获取name对应的集合中元素个数 。

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

num3 = conn.sunion('num1', 'num2') # 并集
复制代码

sinter(keys, args):获取多个集合的交集。

sismember(name, value):检查value是不是name对应的集合的成员, 返回布尔值。

smembers(name):检查value是不是name对应的集合的成员。

smembers(name):获取name对应的集合的全部成员。

spop(name):从集合中随机移除一个成员,并将其返回。

srandmember(name, numbers):从name对应的集合中随机获取 numbers 个元素。

srem(name, values):在name对应的集合中删除某些值

sscan_iter(name, match=None, count=None):用于增量迭代分批获取元素,避免内存消耗太大。

zset类型

有序集合,元素为string类型,元素惟一不重复。元素的排序须要根据另一个值来进行比较,因此,对于有序集合,每个元素有两个值,即:值和分数,分数专门用来作排序。

zadd(name, args, kwargs):在name对应的有序集合中添加元素。

conn.zadd("zz", {"n1":1,"n2":2,"n3":3,"n4":4})
复制代码

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

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

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

zrange( name, start, end, desc=False, withscores=False, score_cast_func=float):按照索引范围获取name对应的有序集合的元素。

# 参数说明
    name    redis的name
    start   有序集合索引发始位置
    end     有序集合索引结束位置
    desc    排序规则,默认按照分数从小到大排序
    withscores  是否获取元素的分数,默认只获取元素的值
    score_cast_func 对分数进行数据转换的函数
    
# Python操做
aa = conn.zrange("znum1",0,1,desc=False,withscores=True,score_cast_func=int)
print(aa)	# [(b'n1', 1), (b'n2', 4)] 
复制代码

zscore(name, value):获取name对应有序集合中,value对应的分数 。

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

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

zrem('zz', ['s1', 's2'])
复制代码

zremrangebyrank(name, min, max):根据排行范围删除,即 '索引值'删除。

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

结语

文章首发于微信公众号程序媛小庄,同步于掘金

码字不易,转载请说明出处,走过路过的小伙伴们伸出可爱的小指头点个赞再走吧(╹▽╹)

相关文章
相关标签/搜索