你还不知道?这些Redis的基本操作一定要掌握(1)

Redis Server 版本 6.0.5
Python Redis 版本 3.5.3
Python 版本 3.8

import redis
redis.VERSION
结果:(3, 5, 3)
r = redis.Redis(host='localhost', port=32779, decode_responses=True, password='XXXXXXXXX', db=2)   # host是redis主机,需要redis服务端和客户端都启动 redis默认端口是6379
r.set('name', 'tabll', ex=500)  # key是"foo" value是"bar" 将键值对存入redis缓存
print(r['name'])
print(r.get('name'))  # 取出键name对应的值
print(type(r.get('name')))
结果:
tabll
tabll
<class 'str'>
r.info
结果:<bound method Redis.info of Redis<ConnectionPool<Connection<host=localhost,port=32779,db=2>>>>

键值对

r.set('name', 'tabll', ex=500)
结果:True
r.exists('name')
结果:1
r.delete('name')
结果:1
r.get('name')

批量键值对

r.set('name1', 'tabll1', ex=500)
r.set('name2', 'tabll2', ex=500)
结果:True
r.mget(['name1', 'name2'])  # 批量获取键值对
结果:['tabll1', 'tabll2']
r.mset({'name3' : 'tabll3', 'name4' : 'tabll5'})  # 批量设置键值对
结果:True
r.mget(['name3', 'name4'])  # 批量获取键值对
结果:['tabll3', 'tabll5']
r.delete('name1')
结果:1

过期和 SET 拓展

r.expire('name', 5)  # 设置过期时间为 5 秒
结果:False
r.get('name')
r.setnx('name', 'tabll2')  ## 如果 name 不存在则创建
结果:True

计数

r.set('counter', 1)
结果:True
r.incr('counter')  # 自增 1
结果:2
r.incrby('counter', 5)  # 自增 5
结果:7
r.set('maxcounter', 9223372036854775807, ex=50)
结果:True
#r.incr('maxcounter')  # 会报错,超出了最大值 它的范围是 signed long 的范围

列表 LinkedList

弹出最后一个元素后自动回收内存

队列

右边进左边出

r.rpush('books', '123')
结果:1
r.llen('books')  # 队列长度
结果:1
r.lpop('books')  # 取出
结果:'123'

右边进右边出

r.rpush('books', '123')
结果:1
r.llen('books')  # 队列长度
结果:1
r.rpop('books')  # 取出
结果:'123'

慢操作

r.rpush('books', 'php')
r.rpush('books', 'python')
r.rpush('books', 'java')
结果:3
r.lindex('books', 1)  # 复杂度 O(n) 慎用
结果:'python'
r.lrange('books', 0, -1)  # 显示范围内数据 复杂度 O(n) 慎用
结果:['php', 'python', 'java']
r.ltrim('books', 1, -1)  # 截取保留范围内数据 复杂度 O(n) 慎用
结果:True
r.lrange('books', 0, -1)
结果:['python', 'java']
r.ltrim('books', 1, 0)
结果:True
r.llen('books')
结果:0

快速列表 QuickList

列元素较少时是压缩列表(ZipList),使用一块连续的内存存储,所有元素彼此紧挨

数据量多时才会改成快速列表(QuickList),因为普通链表需要的附加指针空间太大,加重内存碎片化,浪费空间

QuickList 其实就是多个 ZipList 像糖葫芦一样串起来的

字典 Hash

无序字典,是 数组 + 链表 的二维结构,第一维 hash 的数组位置碰撞时,会将碰撞的元素用链表串联起来

ReHash 操作

使用渐进式 rehash 策略

保留新旧两个 hash,途中查询时同时查询两个 hash 结构,结束后只保留新的

优点,和字符串比可以部分读取,缺点,和字符串比存储消耗大

r.hset('books', 'java', 'this is java')
r.hset('books', 'php', 'this is php')
r.hset('books', 'python', 'this is python')
结果:1
r.hgetall('books')
结果:{'java': 'this is java', 'php': 'this is php', 'python': 'this is python'}
r.hlen('books')
结果:3
r.hget('books', 'php')
结果:'this is php'
r.hset('books', 'php', 'this is new php')  #  更新操作返回 0
结果:0
r.hget('books', 'php')
结果:'this is new php'

hmset 在 Redis 4.0 版本被弃用:

r.hmset('books', {'java' : 'java', 'php' : 'php'})  # 不推荐使用 复杂度 O(n) 慎用
结果:
<ipython-input-41-1d4d1284b692>:1: DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead.
  r.hmset('books', {'java' : 'java', 'php' : 'php'})  # 不推荐使用 复杂度 O(n) 慎用
True
r.hget('books', 'php')
结果:'php'
r.hset('user-tabll', 'age', 17)  # 新增返回 1,修改返回 0
结果:0
r.hincrby('user-tabll', 'age', 2)  # 自增使用 hincrby
结果:19

集合 Set

内部键值对无序唯一

有去重功能,可以保证统一用户不会中奖两次

r.delete('books')
结果:1
r.sadd('books', 'python')
结果:1
r.sadd('books', 'python')  # 重复项则返回 0
结果:0
r.sadd('books', 'php', 'c')  # 新增了几个就返回几
结果:2
r.smembers('books')  # 无序,与插入顺序无关
结果:{'c', 'php', 'python'}
r.sismember('books', 'c')  #  查询某个 value 是否存在
结果:True
r.scard('books')  # 获取总个数
结果:3
r.spop('books')  # 弹出一个
结果:'c'
r.spop('books')
结果:'python'
r.delete('books')
结果:1

有序列表 ZSet

一方面是一个 Set,另一方面它每个值有一个 score,表示这个值的排序权重

内部实现使用的是一个叫做跳跃列表的数据结构

r.zadd('books', {'php 666': 6.6})
结果:1
r.zadd('books', {'java 666': 6.7, 'c 666': 6.8})
结果:2
r.zrange('books', 0, -1)  # 列出区间内的列表
结果:['php 666', 'java 666', 'c 666']
r.zrevrange('books', 0, -1)  # 倒序列出区间内的列表
结果:['c 666', 'java 666', 'php 666']
r.zcard('books')  # 计算个数
结果:3
r.zscore('books', 'php 666')  # 获取指定 value 的 score (可能存在有精度问题)
结果:6.6
r.zrank('books', 'c 666')  # 获取排名 (分数低的在前)
结果:2
r.zrangebyscore('books', 6.6, 6.7)  # 根据分值区间列出 [6.6, 6.7]
结果:['php 666', 'java 666']
r.zrem('books', 'php 666')  # 移除
结果:1
r.delete('books')
结果:1

跳跃列表

相当于多层级的金字塔

可以类似于:亚洲->中国->浙江省->杭州市->上城区->中华路->XX号