• 数据的存储--Redis缓存存储


    Redis缓存存储

    Redis是一个基于内存的 、高效的键值型非关系型数据库,存取效率极高,而且支持多种数据存储结构,使用起来也非常简单。

    1.准备工作

    安装Redis并能正常运行。除了安装好Redis数据库外,还需要安装好redis-py库,即用来操作Redis的Python包,可以使用pip3来安装:

    pip3 install redis
    
    • 1
    2.Redis和StrictRedis

    redis-py库提供Redis和StrictRedis两个类,用来实现Redis命令对应的操作。

    StrictRedis类实现了绝大部分官方的Redis命令,参数也一一对应,例如set方法就对应Redis命令的set方法。而Redis类是StrictRedis类的子类,其主要功能是向后兼容旧版本库里的几个方法。为了实现兼容,Redis类是StrictRedis类的子类,其主要功能是向后兼容旧版库里的几个方法。为了实现兼容,Redis类对方法做了改写,例如将lrem方法中value和num参数的位置互换,这和Redis命令行的命令参数是不一致的。官方推荐使用StrictRedis类。

    3.连接Redis

    我们先在本地安装好Redis,并运行在6379端口,将密码设置为123456。可以用如下实例连接Redis并测试:

    from redis import StrictRedis
    
    redis = StrictRedis(host='localhost', port=6379, db=0, password='123456')
    redis.set('name', 'Bob')
    print(redis.get('name'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里传入了Redis的地址、运行端口、使用的数据库和密码信息。在默认不传数据的情况下,这4个参数分别为localhost、6379、0和None。然后声明了一个StrictRedis对象,并调用对象的set()方法,设置了一个键值对。最后调用get方法获取了设置的键值并打印出来。

    运行结果如下:

    b'Bob'
    
    • 1

    这说明我们成功连接了Redis,并且可以执行set和get操作了。

    当然,还可使用ConnectionPool来连接Redis,实例代码如下:

    from redis import StrictRedis, ConnectionPool
    
    pool = ConnectionPool(host='localhost', port=6379, db=0, password='123456')
    redis = StrictRedis(connection_pool=pool)
    
    • 1
    • 2
    • 3
    • 4

    这样的连接效果是一样的。观察源码可以发现,StrictRedis内其实就是用host和port等参数又构造了一个ConnectionPool,所以直接将ConnectionPool当作参数传给StrictRedisy也一样。

    另外,ConnectionPool还支持通过URL来构建连接。URL支持的格式有如下3种:

    redis://[:password]@host:port/db
    rediss://[:password]@host:port/db
    unix://[:password]@/path/to/socket.sock?db=db
    
    • 1
    • 2
    • 3

    这3种URL分别表示创建Redis TCP连接、Redis TCP+SSL连接、Redis UNIX socket连接。我们只需要构造其中任意一种即可,其中password部分如果有则可以写上,如果没有也可以省略。下面再用URL连接演示一下:

    url = 'redis://123456@localhost:6379/0'
    pool = ConnectionPool.from_url(url)
    redis = StrictRedis(connection_pool=pool)
    
    • 1
    • 2
    • 3

    这里我们使用的是第一种格式。首先,声明一个Redis连接字符串,然后调用from_url方法创建ConnectionPool,接着将其传给StrictRedis即可完成连接,所以使用URL的连接方式还是比较方便的。

    4.键操作
    键的一些判断和操作方法
    方 法作 用参数说明实 例实例说明实例结果
    exists(name)判断一个键是否存在name:键名redis.exists(‘name’)是否存在name这个键True
    delete(name)删除一个键name:键名redis.delete(‘name’)删除name这个键1
    type(name)判断键类型name:键名redis.type(‘name’)判断name这个键的类型b’string’
    keys(pattern)获取所有符合规则的键pattern:匹配规则redis.keys(‘n*’)获取所有以n为开头的键[b’name’]
    randomkey()获取随机的一个键randomkey()获取随机的一个键b’name’
    rename(src, dst)对键重命名src:原键名
    dst:新键名
    redis.rename(‘name’, ‘nickname’)将name重命名为nicknameTrue
    dbsize()获取当前数据库中键的数目dbsize()获取当前数据库中键的数目100
    expire(name, time)设定键的过期时间,单位为秒name:键名
    time:秒数
    redis.expire(‘name’, 2)将name键的过期时间设置为2秒True
    ttl(name)获取键的过期时间,单位为秒name:键名redis.ttl(‘name’)获取name这个键的过期时间2秒True
    move(name, db)将键移动到其他数据name:键名
    db:以往的数据库代号
    move(‘name’, 2)将name键移到2号数据库True
    flushdb()删除当前所选数据库中的所有键flushdb()删除当前所有选数据库中的所有键True
    flushall()删除所有数据库中的所有键flushall()删除所有数据库中的所有键True
    5. 字符串操作

    Redis支持最基本的键值对存储,相关方法总结如下表:

    键值对存储的相关方法
    方 法作 用参数说明实 例实例说明实例结果
    set(name, value)将数据中指定键名对应的键值赋值为字符串valuename:键名
    value:值
    redis.set(‘name’, ‘Bob’)将name这个键对应的键值为BobTrue
    get(name)返回数据中指定键名对应的键值name:键名redis.get(‘name’)返回name这个键对应的键值b’Bob’
    getset(name, value)将数据库中指定键名对应的键值赋值为字符串value,并返回上次的valuename:键名
    value:新值
    redis.getset(‘name’, ‘Mike’)将name这个键对应的键值赋值为Mike,并返回上次的valueb’Bob’
    mget(keys, *args)返回由多个键名对应的value组成的列表keys:键名序列Redis.mget([‘name’, ‘nickname’])返回name和nickname对应的value[b’Mike’, b’Miker’]
    sentx(name, value)如果不存在指定的键值对,则更新value,否则保持不变name:键名redis.setnx(‘newname’, ‘James’)如果不存在newname这个键名,则设置相应键值对,对应键值为James第一次的运行结果是True,第二次的运行结果是False
    setex(name,time,value)设置键名对应的键值为字符串类型的value,并指定此键值的有效期name:键名
    time:有效期valu e:值
    redis.set(‘name’, 1, ‘James’)将name这个键的值设置为James,有效期设置为1秒True
    setrange(name, offset,value)设置指定键名对应的键值的子字符串name:键名
    offset:偏移量value:子字符串
    redis.set(‘name’, ‘Hello’)
    redis.setrange(‘name’, 6, ‘World’)
    将name这个键对应的键值赋值为Hello,并在该键值中index为6的位置补充World11,修改后的字符串长度
    mset(mapping)批量赋值mapping:字典或关键字参数redis.mset({‘name1’:‘Durant’, ‘name2’:‘James’})将name1赋值为Durant,name2赋值为JamesTrue
    msetnx(mapping)指定键名均不存在时,才批量赋值mapping:字典或关键字参数redis.msetnx({‘name3’:‘Smith’, ‘name4’:‘Curry’})在name3和na me4均不存在的情况下,才为二者赋值True
    incr(name, amount=1)对指定键名对应的键值做增值操作,默认增1。如果指定键名不存在,则创建一个,并键值设为amountname:键名amount:增加的值redis.incr(‘age’, 1)将age对应的键值增加1。如果不存在age这个键名,则创建一个,并设置键值为11,即修改后的值
    decr(name, amount=1)对指定键名对应的键值做减值操作,默认减1。如果键不存在,则创建一个,并将键值设置为amountname:键名
    amount:减少的值
    redis.decr(‘age’, 1)将age对应的键值减1。如果不存在age这键名,则创建一个,并设置键值为11,即修改后的值
    append(key, value)对指定键名的键值附加字符串valuekey:键名redis.append(‘nickname’:‘OK’)在键名nickname对应的键值后面追加字符串OK13,即修改后的字符串长度
    substr(name, start, end=-1)返回指定键名对应的键值的子字符串name:键名
    start:起始索引
    end:终止索引,默认为1,表示截取到末尾
    redis.substr(‘name’, 1, 4)返回键名name对应的键值的子字符串,截取键值字符串中索引为1~4度字符串b’ello’
    getrange(key,start,end)获取指定键名对应的键值中从start到end位置的子字符串key:键名
    start:起始索引
    end:终止索引
    redis.getrange(‘name’, 1, 4)返回键名name对应的键值的子字符串。截取键值字符串中索引为1~4的字符b’ello’
    6.列表操作

    Redis提供了列表存储,列表内的元素可以重复,而且可以从两端存储,操作列表的方法见下表:

    列表的操作方法
    方 法作 用参数说明实 例实例说明实例结果
    rpush(name, *values)在键名为name的列表末尾添加值为value的元素,可以传入多个valuename:键名
    values:值
    redis.rpush(‘list’, 1, 2, 3)向键名为list的列表尾添加1,2,33,即列表大小
    lpush(na me,*values)在键名为name的列表头部添加值为value的元素,可以传入多个valuename:键名
    values:值
    redis.lpush(‘list’, 0)的值向键名为list的列表头部添加04,即列表大小
    llen(name)返回键名为name大列表的长度name:键名redis.llen(‘list’)返回键名为list的列表长度4
    lrange(name, start, end)返回键名为name的列表中索引从start到en d之间的元素name:键名
    start:起始索引
    end:终止索引
    redis.lrange(‘list’, 1, 3)返回索引从1到3对应的列表元素[b’3’,b’2’, b’1’]
    ltrim(name, start, end)截取键名为name的列表,保留索引从start到end之间的元素name:键名
    start:起始索引
    end:终止索引
    ltrim(‘list’, 1, 3)保留键名为list的列表中索引从1到3之间的元素True
    lindex(name,index)返回键名为name的列表中index位置的元素name:键名
    index:索引位置
    value:值
    redis.lindex(‘list’, 1)返回键名为list的列表中索引为1的元素b’2’
    lset(name, index,value)给键名为name的列表中index位置的元素赋值,如果index越界就报错name:键名
    index:索引位置
    value:值
    redis.lset(‘list’, 1, 5)将键名为list的列表中索引为1的位置赋值为5True
    lrem(name, count, vlaue)删除键名为name的列表中count个值为value的元素name:键名
    count:删除个数
    value:值
    redis.lpop(‘list’,2,3)删除键名为list的列表中的两个32,即删除的个数
    lpop(name)返回并删除键名为name的列表中的首元素name:键名redis.lpop(‘list’)返回并删除键名为list的列表中国内地第一个元素b’5’
    rpop(name)返回并删除键名为name的列表中的尾元素name:键名redis.rpop(‘list’)返回并删除键名为list的列表中的最后一个元素b’2’
    blpop(keys, timeout=0)返回并删除指定键名对应的列表中的首个元素。如果列表为空,则一直阻塞等待keys:键名序列
    timeout:超时等待时间,0表示一直等待
    redis.blpop(‘list’)返回并删除键名为list的列表中的第一个元素[b’5’]
    brpop(keys, timeout=0)返回并删除键名为name的列表中的尾元素。如果列表为空,则一直阻塞等待keys:键名序列
    timeout:超时等待时间,0表示一直等待
    redis.brpop(‘list’)返回并删除键名为list的列表中最后一个元素[b’2’]
    rpoplpush(src, dst)返回并删除键名为src的列表中的尾元素,并将该元素添加到键名为dst的列表的头部src:源列表的键名
    dst:目标列表的键名
    redis.rpoplpush(‘list’,‘list2’)删除键名为list的列表中的最后一个元素,并将其添加到键名为list2的列表的头部,然后返回b’2’
    7.集合操作

    Redis还提供了集合存储,集合中的元素都是不重复的,操作集合的方法如下表:

    集合的操作方法
    方 法作 用参数说明实 例实例说明实例结果
    sadd(name, *values)向键名为name的集合中添加元素name:键名
    values:值,可以为多个
    redis.sadd(‘tags’, ‘Book’, ‘Tea’, ‘Coffee’)向键名为tags的集合中添加Book、Tea和Coffee这3项内容3,即添加的数据个数
    srem(name, *values)从键名为name的集合中删除元素name:键名
    values:值,可以为多个
    redis.srem(‘tags’, ‘Book’)从键名为tags的集合中删除Book1,即删除的数据个数
    spop(name)随机返回并删除键名为name的集合中的一个元素name:键名redis.spop(‘tags’)随机删除并返回键名为tags的集合中的某元素b’Tea’
    smove(src,dst, value)从键名为src的集合中移除value,并将其添加到dst对应的集合src:源集合
    dst:目标集合
    value:元素值
    redis.smove(‘tags’, ‘tags2’, ‘Coffee’)从键名为tags的集合中删除元素Coffee,并将其添加到键名为tags2的集合中True
    scard(name)返回键名为name的集合中的元素个数name:键名redis.scard(‘tags’)获取键名为tags的集合中的元素个数3
    sismemeber(name, value)测试member是否是键名为name的集合中的元素name:键值redis.sistmember(‘tags’, ‘Book’)判断Book是否是键名为tags的集合中的元素True
    sinter(keys, *args)返回所有给定键名的集合的交集keys:键名序列redis.sinter([‘tags’, ‘tags2’])返回键名为tags的集合和键名为tags2的集合的交集{b’Coffee’}
    sinterstore(dest, keys,*args)求多个集合的交集,并将交集保存到键名为dest的集合keys:键名
    dest:结果集合
    redis.sinterstore(‘inttag’, [‘tags’, ‘tags2’])求键名为tags的集合和键名为tags2的集合的交集,并将其保存为键名为inttag的集合1
    sunion(keys, *args)返回所有给定键名的集合的并集keys:键名序列redis.sunion([‘tags’, ‘tags2’])返回键名为tags的集合和键名为tags2的集合的并集{b’Coffee’,b’Book’,b’Pen’}
    sunionstore(dest, keys, *args)求多个集合的并集,并将并集保存到键名为dest的集合keys:键名序列
    dest:结果集合
    redis.sunionstore(‘inttag’, [‘tags’: ‘tags2’])求键名为tags的集合和键名为tags的集合并集,并将其保存为键名是inttag的集合3
    sdiff{keys, *args}返回所有给定键名的集合的差集keys:键名序列
    redis.sdiff([‘tags’, ‘tags2’])返回键名为tags的集合和键名为tags2的集合的差集{b’Book’, b’Pen’}
    sdiffstore(dest, keys, *args)求多个集合的差集,并将差集保存到键名为dest的集合keys:键名序列
    dest:结果集合
    redis.sdiffstore(‘intag’, [‘tags’, ‘tags2’])求键名为tags的集合和键名为tags2的集合的差集,并将其保存为键名是inttag的集合3
    smembers(name)返回键名为name的集合中的所有元素name:键名redis.smembers(‘tags’)返回键名为tags的集合中的所有元素{b’Pen’,b’Book’, b’Coffeee’}
    srandmember(name)随机返回键名为name的集合中的一个元素,但不删除该元素name:键值redis.srandmember(‘tags’)随机返回键名为tags的集合中的一个元素srandmember(name)
    8.有序集合操作

    有序集合比集合多了一个分数字段,利用该字段可以对集合中的数据进行排序,操作有序集合的方法总结如下表:

    有序集合的操作方法
    方 法作 用参数说明实 例实例说明实例结束
    zadd(name, args,*kwargs)向键名为name的有序集合中添加元素。score字段用于排序,如果该元素存在,则更新各元素的顺序name:键名
    args:可变参数
    redis.zadd(‘grade’,100,‘Bob’,98,‘Mike’)向键名为grade的有序集合中添加Bob(对应score为100)、Mike(对应score为98)2,即添加的元素个数
    zrem(name, *values)删除键名为name的有序集合中的元素name:键名
    values:元素
    redis.zrem(‘grade’, ‘Mike’)从键名为grade的有序集合中删除Mike1,即删除的元素个数
    zincrby(name,value, amount=1)如果键名为name的有序集合中已经存在元素value,则将该元素的score增加amount;否则向该元素中添加value元素,其score的值为amountname:键名
    values:元素
    amount:增长的score值
    redis.zincrby(‘grade’, ‘Bob’,-2)将键名为grade的有序集合中Bob元素的score减298.0,即修改后的值
    zrank(name,value)返回键名为name的有序集合中value元素的排名,或名次(对各元素按照score从小到大排序)name:键名
    value:元素值
    redis.zrank(‘grade’, ‘Amy’)得到键名为grade的有序集合中Amy的排名1
    zrevrank(name, value)返回键为name的有序集合中value元素的倒数排名,或名次(对各元素按照score从大到小排序)name:键名
    value:元素值
    redis.zrevrank(‘grade’, ‘Amy’)得到键名为grade的有序集合中Amy的倒数排名2
    zrevrange(name, start,end,withscores=False)返回键名为name的有序集合中名次索引从start到end之间的所有元素(按照score从大到小排序)name:键名
    start:开始索引
    end:结束索引
    withscores:是否带score
    redis.zrevrange(‘grade’, 0, 3)返回键名为grade的有序集合中的前四名元素[b’Bob’,b’Mike’,b’Amy’,b’James’]
    zrangebyescore(name, min, max,start=None,num=None,withscores=False)返回键名为name的有序集合中score在给定区间的元素name:键名
    min:最低
    max:最高score
    start:起始索引
    num:个数withscores:是否带score
    redis.zrangebyscore(‘grade’, 80,95)返回键名为grade的有序集合中score在80和95之间的元素[b’Bob’,b’Mike’,b’Amy’, b’James’]
    zcount(name,min,max)返回键名为name的有序集合中score在给定区间的元素数量name:键名
    min:最低score
    max:最高score
    redis.zcount(‘grade’, 80,95)返回键名为grade的有序集合中score在80和95之间的元素个数4
    zcard(name)返回键名为name的有序集合中的元素个数name:键名redis.zcard(‘grade’)获取键名为grade的有序集合中元素的个数3
    zremrangebyrank(name, min, max)删除键名为name的有序集合中排名在给定区间的元素name:键名
    min:最低名次
    max:最高名次
    redis.zremrangebyrank(‘grade’, 0, 0)删除键名为grade的有序集合中排名第一的元素1,即删除的元素个数
    zremrangebyscore(name,min,max)删除键名为name的有序集合中score在给定区间的元素name:键名
    min:最低score
    max:最高score
    redis.zremrangebyscore(‘grade’, 80, 90)删除键名为grade的有序集合中score在80和90之间的元素1,即删除的元素个数
    9.散列操作

    Redis还提供了散列表这种数据结构,我们可以用name指定一个散列表的名称,表内存储着多个键值对,操作散列表的方法总结如下表:

    散列表的操作方法
    方 法作 用参数说明实 例实例说明实例结果
    hset(name,key,value)向键名为name的散列表中添加映射name:散列表键名
    key:映射键名
    value:映射键值
    hset(‘price’, ‘cake’, 5)向键名为price的散列表中添加映射关系,cake的值为51,即添加的映射个数
    hsetnx(name, key, value)如果键名为name的散列表中不存在给定映射,则向其中添加此映射name:散列表键名
    key:映射键名
    value:映射键值
    Hsetnx(‘price’, ‘book’, 6)向键名为price的散列表中添加映射关系,book的值为61,即添加的映射个数
    hget(name, key)返回键名为name的散列表中key对应的值name:散列表键名
    key:映射键名
    redis.hget(‘price’, ‘cake’)获取键名为price的散列表中键名cake的值5
    hmset(name, mapping)向键名为name的散列表中批量添加映射name:散列表键名
    mapping:映射字典
    redis.hmset(‘price’,{‘banana’:2, ‘pear’:6})向键名为price的散列表中批量添加映射True
    hincrby(name, key,amount=1)将键名为name的散列表中的映射键值增加amountname:散列表键名
    key:映射键名
    amount:增长量
    redis.hincrby(‘price’, ‘apple’, 3)将键名为price的散列表中apple的键值增加36,修改后的值
    hexists(name, key)返回键名为name的散列表中是否存在键名key的映射name:散列表键名
    key:映射键名
    redis.hexists(‘price’, ‘banana’)返回键名为price的散列表中是否存在键名为banana的映射True
    hdel(name, *keys)在键名为name的散列表中,删除具有给定键名的映射name:散列表键名
    keys:映射键名序列
    redis.hdel(‘price’, ‘banana’)从键名为price的散列表中,删除键名为banana的映射True
    hlen(name)获取键名为name的散列表中有多少个映射name:散列表键名redis.hlen(‘price’)获取键名为price的散列表中映射的个数6
    hkeys(name)获取键名为name的散列表中的所有映射键名name:散列表键名redis.hkeys(‘price’)获取键名为price的散列表中的所有映射键名[b’cake’,b’book’,b’banana’,b’pear’]
    hvals(name)获取键名为name的散列表中的所有映射键值name:散列表键名redis.hvals(‘price’)获取键名为price的散列表中的所有映射键值[b’5’,b’6’,b’2’,b’6’]
    hgetall(name)获取键名为name的散列表中的所有映射键值对name:散列表键名redis.hgetall(‘price’)获取键名为price的散列表中的所有映射键值对{b’cake’:b’5’,b’book’:b’6’,b’orange’:b’7’,b’pear’:b’6’}
  • 相关阅读:
    简述Web3.0
    乔迁之喜!泛微软件园启用,欢迎新老朋友来坐坐
    mac pro M1(ARM)安装:centos8.0虚拟机
    HCIP之BGP的路由聚合
    【Pytorch实用教程】Pytorch中nn.Sequential的用法
    JVM虚拟机:CMS垃圾回收器的日志分析
    Linux C 线程
    机器视觉常见的问题及解决
    java面试题-设计模式基础
    mac 启动mysql Error: Failure while executing; `/bin/launchctl bootstrap gui/501
  • 原文地址:https://blog.csdn.net/weixin_41905135/article/details/134449992