一、简介
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
二、数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
string(字符串)
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
hash(哈希)
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
list(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。
Set(集合)
Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
三、事务
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务。
- 命令入队。
- 执行事务。
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
四、redis常用命令及基本用法
1、redis连接
import redis r =redis.Redis(host='127.0.0.1',port=6379)
2、也可以使用连接池连接
import redis p = redis.ConnectionPool(host='127.0.0.1', port=6379)
3、基本命令string
import redis r =redis.Redis(host='127.0.0.1',port=6379) #1、存储数据set(name, value, ex=None, px=None, nx=False, xx=False) #ex,过期时间(秒) #px,过期时间(毫秒) #nx,如果设置为True,则只有name不存在时,当前set操作才执行 #xx,如果设置为True,则只有name存在时,当前set操作才执行 r.set('name','pt') #2、批量设置值mset(*args, **kwargs) r.mset(k1='v1', k2='v2') #3.批量获取mget(keys, *args) r.mget("k1","k2") #4.修改值getset(name, value),将k1的值换成v2 r.getset("k1","v2"))
4、基本命令hash
import redis r =redis.Redis(host='127.0.0.1',port=6379) #1、单个增加--修改(单个取出)--没有就新增,有的话就修改 #hset(name, key, value) #name对应的hash中设置一个键值对(不存在,则创建;否则,修改) #参数: #name,redis的name #key,name对应的hash中的key #value,name对应的hash中的value r.hset("name_hash","k1","v1") #2、hsetnx(name, key, value)只能新建 r.hsetnx("name_hash","k1","v1") #3、批量增加(取出) #hmset(name, mapping) #在name对应的hash中批量设置键值对 #参数: #name,redis的name #mapping,字典,如:{'k1':'v1', 'k2': 'v2'} r.hmset('xx', {'k1':'v1', 'k2': 'v2'}) #4、取出单个 #hget(name,key) #在name对应的hash中获取根据key获取value r.hget("name_hash","k2") #5、批量取出 #hmget(name, keys, *args) #在name对应的hash中获取多个key的值 #参数: #name,reids对应的name #keys,要获取key集合,如:['k1', 'k2', 'k3'] #*args,要获取的key,如:k1,k2,k3 r.hmget('xx', 'k1', 'k2') #6、取出所有的键值对 #hgetall(name) #获取name对应hash的所有键值 r.hgetall("name_hash") #7、删除键值对 #hdel(name,*keys) #将name对应的hash中指定key的键值对删除 r.hdel("name_hash","k1") 删除一个键值对
5、基本命令list
import redis r =redis.Redis(host='127.0.0.1',port=6379) #1、增加(类似于list的append,只是这里是从左边新增加)--没有就新建 #lpush(name,values) #在name对应的list中添加元素,每个新的元素都添加到列表的最左边 r.lpush('oo', 11,22,33) #2、增加(从右边增加)--没有就新建 r.lpush('oo', 11,22,33) #3、新增(固定索引号位置插入元素) linsert(name, where, refvalue, value)) #在name对应的列表的某一个值前或后插入一个新值 #参数: #name,redis的name #where,BEFORE或AFTER #refvalue,标杆值,即:在它前后插入数据 #value,要插入的数据 r.linsert("foo_list1","before","22","33") #4、修改 #lset(name, index, value) #对name对应的list中的某一个索引位置重新赋值 #参数: #name,redis的name #index,list的索引位置 #value,要设置的值 r.lset("name_list",4,20) #5、删除 #lrem(name, value, num) #在name对应的list中删除指定的值 #参数: #name,redis的name #value,要删除的值 #num, num=0,删除列表中所有的指定值; #num=2,从前到后,删除2个; num=1,从前到后,删除左边第1个 #num=-2,从后向前,删除2个 r.lrem("foo_list1","2",1) #6、取值(根据索引号取值) lindex(name, index) 在name对应的列表中根据索引获取列表元素 r.lindex("name_list",0)
6、基本命令set
import redis r =redis.Redis(host='127.0.0.1',port=6379) #1、新增 #sadd(name,values) #name对应的集合中添加元素 r.sadd("set1",33,44,55,66) #2、 获取元素个数 类似于len scard(name) #获取name对应的集合中元素个数 r.scard("set1") #3、 获取集合中所有的成员 smembers(name) #获取name对应的集合的所有成员 r.smembers("set1") #4、删除,随机删除,返回被删除值 #spop(name) r.spop("set1") #5、指定删除 #srem(name, values) r.srem("set1",66)
7、基本命令有序集合
import redis r =redis.Redis(host='127.0.0.1',port=6379) #1、新增 #zadd(name, *args, **kwargs) #在name对应的有序集合中添加元素 r.zadd('zz', 'n1', 1, 'n2', 2) #2、获取有序集合元素个数 类似于len #zcard(name) #获取name对应的有序集合元素的数量 r.zcard('zz') #3、获取name对应的有序集合中分数 在 [min,max] 之间的个数 #zcount(name, min, max) r.zcount("zz",11,22) #4、删除--指定值删除 #zrem(name, values) r.zrem('zz', ['s1', 's2'])
8、其他常规操作
#1 删除 delete(*names) #根据删除redis中的任意数据类型(string、hash、list、set、有序set) #2、检查名字是否存在 #exists(name) #检测redis的name是否存在 r.exists("ste1") True 存在就是True, False 不存在就是False #3、模糊匹配 #keys(pattern='*') #根据模型获取redis的name r.keys(pattern='ss') #4、设置超时时间 #expire(name ,time) #为某个redis的某个name设置超时时间 r.expire(name ,5) #5、 重命名 #rename(src, dst) #对redis的name重命名为 r.rename("name2","name1") #6、获取类型 #type(name) #获取name对应值的类型 r.type("set1") #7、查看所有元素 #scan(cursor=0, match=None, count=None)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通