目录
1. 简介
1.1 优势
1.2 key命名规范
1.3 Key相关命令
2 Redis中数据结构类型
3 String类型
3.1 String常用命令
3.2 String类型的应用场景
4 List类型
4.1 特点
4.2 List常用命令
4.3 List类型应用场景
5 Hash类型(散列)
5.1 特点
5.2 Hash常用命令
5.3 Hash类型应用场景
5.4 Hash类型不适用的场景
6 Set类型(集合)
6.1 特点
6.2 Set相关命令
6.3 应用场景
7 ZSet类型
7.1 特点
7.2 ZSet常用命令
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
规范命名举例
// 文章点赞key
set CONTENT:UP:100
// 文章详情key
set CONTENT:DETAIL:100
说明:如果想要对key进行操作(增删改查等等),需要使用redis提供好的关键字:set、del、get、exists等等,因此需要学习关键字的使用。如下:
命令 说明
set key value 设置key-value键值对
del key 删除一个key
del key1 key2 key3 删除多个key
incr key 将 key对应的value中储存的数字值增一,然后返回。
注意:
[1]如果这个key不存在,那么key的值会先被初始化为0,然后再执行incr操作。
[2]如果这个key对应的value值不是数字,则会返回一个错误。
incrby key step 将key对应的value值增加指定的step。
注意:类似同incr。
decr key 将 key 对应的value中储存的数字值减一,然后返回。
注意:类似同incr。
decrby key decrement 将key减少对应的步长值。
注意:类似同incr。
get key 获取key对应的value值,如果key不存在,则返回nil
mget key1 key2 key3 一次获取多个key的值,如果对应key不存在,则对应返回nil
keys pattern (模糊查找) 查找所有符合给定pattern的key。如下:
[1]keys * 匹配数据库中所有 key 。
[2]keys n?me 匹配 name、neme、nfme 等。
[3]keys n* 匹配 name、neme、naaaaame等。
[4]keys n[ae]me 只能匹配 name、neme。
exists key 检查给定key是否存在。
注意事项:不支持通配符
ttl key (time to live) 查看某个key的剩余过期时间,返回值:
-2 表示这个key已经过期,需要删除掉
-1 表示没有设置过期时间
其它 表示剩余的生存时间,单位为秒
expire key second 指定key的过期时间。
注意:新添加的key,如果没有指定过期时间,则会一直保存。
可以对一个已经带有生存时间的key执行expire命令,
新指定的生存时间会取代旧的生存时间。
rename key newkey 将key改名为newkey。
当key和newkey相同,或者key不存在时,返回一个错误。
当newkey已经存在时,rename命令将覆盖旧值。
type key 查看key对应的value的数据结构类型
其它key命令见redis帮助文档:http://doc.redisfans.com/
Redis的数据结构类型,指的就是Redis的值value的类型。
Redis常用的数据结构类型:String、List、Hash、Set、ZSet。
String类型是redis最常用的数据结构类型,存储的值为字符串
注意:key只能是String类型
命令 说明
set key value 设置一个key,值为value,类型为String类型;如果这个key已经存在,则更新这个key的值。
返回值:1 表示成功、0 表示失败
setnx key value 如果这个key不存在,则设置一个key,值为value;如果key存在,则不做更新。
返回值:1 表示成功、0 表示失败
append key value 如果key已经存在,则将value追加到这个key原先的value值的末尾。
如果这个key不存在,则执行set操作。
incr key 将 key对应的value中储存的数字值增一,然后返回。
注意:
[1]如果这个key不存在,那么key的值会先被初始化为0,然后再执行incr操作。
[2]如果这个key对应的value值不是数字,则会返回一个错误。
incrby key step 将key对应的value值增加指定的step。
注意:类似同incr。
decr key 将 key 对应的value中储存的数字值减一,然后返回。
注意:类似同incr。
decrby key decrement 将key减少对应的步长值。
注意:类似同incr。
help @string 查看string类型的帮助文档
如:热点数据缓存、流水号的自增、短信验证码
相关命令:set key incr、incrby、decr、decrby。
文章内容详情数据
解决多线程的线程安全问题。
redis的key是单线程模式,这就意味一瞬间只有一个线程能够持有这个key,所以可以使用redis解决部分涉及线程安全的业务,比如说抢购、秒杀
流水号自增代码如下
/**
* 获取订单流水号
* @date: 2021/1/5 10:13
* @return: java.lang.String
*/
@GetMapping("/getserialNumber")
@ApiOperation(value = "获取订单流水号", notes = "获取订单流水号")
public String getserialNumber() {
String key = RedisConstants.SERIAL;
Long serial = redisService.incrBy(key, 1);
String format = String.format("%06d", serial);
String stringDate = DateUtil.getStringDate(new Date(), DateUtil.yyyyMMddHHmm);
StringBuilder sb = new StringBuilder("OD");
sb.append(stringDate).append(format);
return sb.toString();
}
【1】基于Linked List实现。
【2】元素是字符串类型。
【3】列表头尾增删快,中间增删慢,增删元素是常态。
【4】从左至右,从0开始,从右至左,从-1开始。
【5】元素可以重复出现。
【6】最多包含2^32-1元素。
数据结构图
代码如下
@ApiOperationSupport(order = 1)
@PostMapping("/commentOrReply")
@ApiOperation(value = "添加评论/回复-(V1.1)", notes = "评论/回复-(V1.1)")
public boolean commentOrReply(@Valid @RequestBody ContentCommentReq contentCommentReq) {
log.info("commentOrReply.req contentCommentReq={}",JSON.toJSONString(contentCommentReq));
String key = RedisConstants.COMMENT+":"+ contentCommentReq.getContentId();
redisService.lSet(key,JSON.toJSONString(contentCommentReq));
return Boolean.TRUE;
}
【1】hash内容由field和与之关联的value组成map键值对组成
【2】key、field和value是字符串类型
【3】一个hash中最多包含2^32-1键值对
--数据结构图:
节省资源
redis每创建一个键,都会为这个键储存一些附加的管理信息(比如这个键的类型,这个键最后一次被访问的时间等等),因此redis的key相对于值来说,更珍贵!!!
reids数据库中的键越多,redis数据库服务器在储存附加管理信息方面耗费的内存就越多,在获取key对应的value值时cpu的开销也会更多。
Hash结构可以将具有关联关系的一组key-value,存储到同一个hash结构中,从而减少key的数量,如下:
因此能使用hash的时候尽量使用hash,这也是hash类型的应用场景。
***对某一个field设置过期时间
如果我们仅仅只对一个字段设置过期,就不能使用hash。因为Redis的key的过期功能只能对键操作,而Hash结构不能单独对某一个filed设置过期功能。
说明:在实际开发中,能使用hash的时候,尽量使用hash!!
【1】无序的、无重复的
【2】元素是字符串类型
【3】最多包含2^32-1元素
数据结构图
新浪微博的共同关注
需求:当用户访问另一个用户的时候,会显示出两个用户共同关注哪些相同的用户
设计:将每个用户关注的用户放在集合中,求交集即可
实现如下:
peter={'john','jack','may'}
ben={'john','jack','tom'}
那么peter和ben的共同关注为:sinter peter ben
结果为{'john','jack'}
【1】类似Set集合
【2】有序的、无重复的
【3】元素是字符串类型
【4】每一个元素都关联着一个浮点数分值(Score),并按照分值从小到大的顺序排列集合中的元素。注意:分值可以相同
【5】最多包含2^32-1元素
数据结构图
业务场景
比如文章点赞、收藏等功能
描述:key = CONTENT:UPLIST:文章ID valeue:userId
为了用户在个人中心点查看我点赞的文章,zSet中有score保存了时间戳 ,为了排序
取消点赞命令:zRemove方法
获取文章点赞数量:zSize方法
/**
* 文章点赞或者取消List
* @param contentId 文章ID
* @param operType 操作类型 1:添加 2:取消
* @date: 2021/1/4 15:25
* @return: java.lang.Long
*/
@GetMapping("commentUpList")
@ApiOperation(value = "文章点赞或者取消List")
public Boolean commentUpList(@RequestParam("contentId") Long contentId,
@RequestParam("operType") int operType,
@RequestParam("userId") Long userId) {
log.info("commentUp.req contentId={},operType={}",contentId,operType);
String key = RedisConstants.CONTENT+":"+RedisConstants.UPLIST +":"+ contentId;
// todo 添加数据库一份数据
if (1 == operType) {
redisService.zAdd(key,userId.toString(),System.currentTimeMillis());
return Boolean.TRUE;
}
redisService.zRemove(key,userId.toString());
// 总条数
Long count = redisService.zSize(key);
log.info("count={}",count);
return Boolean.TRUE;
}
在这里,欢迎各位提出宝贵意见和建议,也欢迎大家来吐槽,帮助我进步!
这是我的公众号,每周会分享一篇文章!
参考文档
Redis【数据结构类型篇】 - 知乎