zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Redis中数据结构类型

2023-09-11 14:20:02 时间

目录

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常用命令


1. 简介

 Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
 Redis 与其他 key - value 缓存产品有以下三个特点:

  •  Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  •  Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  •  Redis支持数据的备份,即master-slave模式的数据备份。

   
1.1 优势

  •  性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  •  丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  •     原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  •     丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

 1.2 key命名规范

  • 键值不需要太长,首先消耗内存过多,其次键值计算成本较高(查询耗时长)
  • 键值不宜过短,可读性较差,通常建议见名知意

规范命名举例

// 文章点赞key
set CONTENT:UP:100 
// 文章详情key
set CONTENT:DETAIL:100 

 1.3 Key相关命令

说明:如果想要对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/

2 Redis中数据结构类型

Redis的数据结构类型,指的就是Redis的值value的类型。

Redis常用的数据结构类型:String、List、Hash、Set、ZSet。

3 String类型

String类型是redis最常用的数据结构类型,存储的值为字符串

注意:key只能是String类型

3.1 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类型的帮助文档

3.2 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();
    }

4 List类型

4.1 特点

【1】基于Linked List实现。
【2】元素是字符串类型。
【3】列表头尾增删快,中间增删慢,增删元素是常态。
【4】从左至右,从0开始,从右至左,从-1开始。
【5】元素可以重复出现。
【6】最多包含2^32-1元素。

数据结构图

4.2 List常用命令

4.3 List类型应用场景

  • 处理顺序类业务。如新浪微博评论、论坛回帖楼层等
  • 聊天室

代码如下

@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;
    }

5 Hash类型(散列)

5.1 特点

【1】hash内容由field和与之关联的value组成map键值对组成
【2】key、field和value是字符串类型
【3】一个hash中最多包含2^32-1键值对

--数据结构图:

5.2 Hash常用命令

5.3 Hash类型应用场景

 节省资源

redis每创建一个键,都会为这个键储存一些附加的管理信息(比如这个键的类型,这个键最后一次被访问的时间等等),因此redis的key相对于值来说,更珍贵!!!

reids数据库中的键越多,redis数据库服务器在储存附加管理信息方面耗费的内存就越多,在获取key对应的value值时cpu的开销也会更多。

Hash结构可以将具有关联关系的一组key-value,存储到同一个hash结构中,从而减少key的数量,如下:

因此能使用hash的时候尽量使用hash,这也是hash类型的应用场景

5.4 Hash类型不适用的场景

***对某一个field设置过期时间

如果我们仅仅只对一个字段设置过期,就不能使用hash。因为Redis的key的过期功能只能对操作,而Hash结构不能单独对某一个filed设置过期功能。

说明:在实际开发中,能使用hash的时候,尽量使用hash!!

6 Set类型(集合)

6.1 特点

【1】无序的、无重复的
【2】元素是字符串类型
【3】最多包含2^32-1元素

数据结构图

6.2 Set相关命令

6.3 应用场景

新浪微博的共同关注

需求:当用户访问另一个用户的时候,会显示出两个用户共同关注哪些相同的用户

设计:将每个用户关注的用户放在集合中,求交集即可

实现如下:

peter={'john','jack','may'}
ben={'john','jack','tom'}
那么peter和ben的共同关注为:sinter peter ben
结果为{'john','jack'}

7 ZSet类型

7.1 特点

【1】类似Set集合
【2】有序的、无重复的
【3】元素是字符串类型
【4】每一个元素都关联着一个浮点数分值(Score),并按照分值从小到大的顺序排列集合中的元素。注意:分值可以相同
【5】最多包含2^32-1元素

数据结构图

7.2 ZSet常用命令

业务场景

比如文章点赞、收藏等功能

描述: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【数据结构类型篇】 - 知乎