Redis系列之常见数据类型应用场景

news2024/11/23 18:35:20

文章目录

  • String
    • 简单介绍
    • 常见命令
    • 应用场景
  • Hash
    • 简单介绍
    • 常见命令
    • 应用场景
  • List
    • 简单介绍
    • 常见命令
    • 应用场景
  • Set
    • 简单介绍
    • 常见命令
    • 应用场景
  • Sorted Set(Zset)
    • 简单介绍
    • 常见命令
    • 应用场景
  • Bitmap
    • 简单介绍
    • 常见命令
    • 应用场景
  • 附录

Redis支持多种数据类型,比如String、hash、list、Set、SortedSet、Streams、Bitmap、Hyperloglog、Geo(物理位置)等等,在 官网也给出了说明,本博客就挑一些比较常有的数据类型说说,本文例子基于Redisson实现

在这里插入图片描述

String

简单介绍

在Redis中,所有的数据都是key-value的数据结构存储的,那么在Redis中这个string类型的value值只能存储String类型的数据?其实不然,redis中string类型的value值是可以支持多种类型的,比如String、Number、Float、Bits等等,但是最大还是只能存储512M。Redis中key也是string类型存储的,所以最大也只能存储512M

常见命令

setget命令就不演示了,下面给出一些常有命令

批量设置多个key

mset tkey1 tvalue tkey2 111

批量获取多个key值

mget tkey1 tkey2

获取长度

strlen tkey

字符串后面追加内容

append tkey tstring

获取指定范围的字符

# 取0~3之间的字符,返回1tst
getrange tkey 0 3

key进行递增(整数)

# 返回1
incr ikey
# 递增指定大小的值,返回124
incrby ikey 124

key进行递增(浮点数)

# 设置初始浮点数值
set fkey 1.2
# 在原来基础上递增2.4,返回3.6
incryfloat fkey 2.4

加上key过期时间

expire tkey 10

分布式锁实现,set if not exists,可以使用setnx单个命令,也可以使用set结合nx命令来实现

# set tkey过期时间10秒,nx:如果键不存在时设置
set tkey aaa ex 10 nx
# setnx命令,相当于set和nx命令一起用
setnx tkey aaa

EX : 设置指定的到期时间(以秒为单位)。

PX : 设置指定的到期时间(以毫秒为单

NX : 仅在键不存在时设置键。

XX : 只有在键已存在时才设置。

String 更多指令请参考官网文档:https://redis.io/commands/?group=string

应用场景

对于Redis String类型的应用场景也比较多,比如很常有的做缓存处理,也可以用于分布式锁、分布式ID

分布式锁的实现主要依赖于命令setnx

分布式ID主要是利用incr这个命令

基于Redis实现一个分布式ID生成器

package com.example.redis.common.handlers;

import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * <pre>
 *      Redis分布式ID生成器
 * </pre>
 *
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2023/11/07 14:18  修改内容:
 * </pre>
 */
@Component
public class RedisIdentifierGenerator implements IdentifierGenerator {

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public Number nextId(Object entity) {
        String key = entity.getClass().getName();
        return redisTemplate.opsForValue().increment(key);
    }

}

Hash

简单介绍

Hash哈希,数据类型也是一种比较常见的数据结构,相对于Redis的string类型而言,其实就是多了一层key(field),所以说只要string类型适用的场景,hash都是支持的

常见命令

hash设置key为hkey,field为a的值

hset hkey a aaaa

获取hkey的field值

hget hkey a

设置多个field值

hmset hkey a 1 b 2 c 3 d 4

获取多个field值

hmget hkey a b c d

获取key所有的field

hkeys hkey

获取key所有field的值

hvals hkey

获取key所有fileld和值

hgetall hkey

在这里插入图片描述

给key某个字段field添加值

hincrby hkey a 10

在这里插入图片描述

对于Hash的更多命令,请参考:https://redis.io/commands/?group=hash

应用场景

对于hash的应用场景,其实只要redis string类型适用的,hash都是适用的,不过hash这种特殊的数据结构,还是适用于一些特殊场景的

  • 存储一个对象类的数据,这个对象的多个字段就对应hash的field
  • 存储一些统计类的数据,比如访问量、点击量等等

如图,如果要统计博客的pv、uv还有评论数量(evaluation_count),随着博客数量的增加存储到数据库里,后面肯定会查询比较慢,所以可以使用redis进行缓存

在这里插入图片描述

使用Redisson来写一个例子:

  @Resource
    private RedissonClient redissonClient;

    @Test
    void contextLoads() throws ExecutionException, InterruptedException {
        RMap<Object, Object> redissonClientMap = redissonClient.getMap("recordMap");
        Map<String,Integer> map = new HashMap<>();
        map.put("pv" , 1000);
        map.put("uv" , 1500);
        map.put("evaluation_count",30)
        redissonClientMap.putAll(map);
        System.out.println(redissonClientMap.addAndGet("pv", 2));
    }   

List

简单介绍

redis中的数据类型存储有序的字符串列表,元素是可以重复,列表的最大长度为2^32-1个元素(4294967295),即每个列表超过40亿个元素

常见命令

左右添加元素

# 左边添加元素
lpush queueList a
lpush queueList b c

# 右边添加元素
rpush queueList d e

左右弹出第一条

# 左边弹出一个元素
lpop queueList
# 右边弹出一个元素
rpop queueList

左右弹出一个元素,并且设置超时,直到无数据弹出或者超时

blpop queueList 10
brpop queueList 10

应用场景

  • 微信公众号、微博等消息流列表

    RDeque<Object> recordList = redissonClient.getDeque("recordList");
    recordList.addFirst("1.新闻1");
    recordList.addFirst("2.新闻2");
    recordList.addFirst("3.新闻3");
    IntStream.range(0,3).forEach(a->{
        System.out.println(recordList.poll());
    });
    
  • 消息队列,使用redis也可以实现消息队列,比如使用rpush/lpop实现简单队列;blpop或者是brpop来实现阻塞读取队列;补充说明,同时streampub/sub(订阅发布模式)、sortedSet等等也是可以实现的

    不过还是不建议使用Redis来实现消息队列,因为我们已经有成熟的MQ框架,使用redis实现队列有可能有下面的问题:

    • 存在内存,可能会有数据丢失,不能重复消费
    • 消费后不能回应,没有ack确认机制

Set

简单介绍

Redis中的Set类型是无序集合,最大存储数量为2^32-1,大概有40亿左右,添加、删除元素的时间复杂度都是O(1)

常见命令

添加一个或者多个元素

sadd skey a b c d e f g h

获取所有的元素

smembers skey

获取集合元素的个数

scard skey

随机获取一个元素

srandmember skey

随机弹出一个元素

spop skey

弹出指定的元素

# 如果两个元素都有,返回2
srem skey a g

检查元素是否存在

# 元素存在返回1
sismember skey e

获取前一个集合有,而后面一个集合没有的元素

sdiff skey skey1

获取集合的交集

sinter skey skey1

获取集合的并集

sunion skey skey1

Set的更多命令请参考:https://redis.io/commands/?group=set

应用场景

  • 抽奖程序,利用spopstandmember随机弹出元素

    RSet<String> recordSet = redissonClient.getSet("recordSet");
    List<String> members = Lists.newArrayList("alice", "tim","tom" , "风清扬", "jack" );
    recordSet.addAll(members);
    RFuture<Set<String>> threeSet = recordSet.removeRandomAsync(3
                                                               );
    RFuture<Set<String>> twoSet = recordSet.removeRandomAsync(2
                                                             );
    RFuture<Set<String>> oneSet = recordSet.removeRandomAsync(1
                                                             );
    System.out.println("三等奖:"+threeSet.get());
    System.out.println("二等奖:"+twoSet.get());
    System.out.println("一等奖:"+oneSet.get());
    
  • 集合交集(sinter)、并集(sunion)的场景,可以实现共同关注等场景

    RSet<Object> tom = redissonClient.getSet("tom");
    tom.addAll(Lists.newArrayList("令狐冲","james","风清扬"));
    RSet<Object> jack = redissonClient.getSet("jack");
    jack.addAll(Lists.newArrayList("令狐冲","tim","jack"));
    System.out.println("共同关注的人:"+tom.readIntersectionAsync("jack").get());
    
  • sadd 集合存储,实现点赞、签到的业务场景

Sorted Set(Zset)

简单介绍

相对于set来说,sorted set是一种有序的set,排序是根据每个元素的score排序的,score相同时根据key的ASCII码排序

在这里插入图片描述

常见命令

批量添加元素

zadd z1 10 a 20 b 30 c 40 d 50 e 60 f 70 g 80 h 90 i

在这里插入图片描述

根据分数从低到高

zrange z1 0 -1 withscore

在这里插入图片描述

根据分数从高到低

zrevrange z1 0 -1 withscores

根据分数范围取值

zrangebyscore z1 20 30

移除元素

zrem z1 i

获取有序集合个数

zcard z1

给某个元素加分值

zincrby z1 20 a

获取范围内的个数

zcount z1 50 60

返回指定元素的索引值

# 假如d元素排在第4位,索引值就返回3
zrank z1 d

获取元素的分数

zscore z1 h

Sorted Set的更多命令请参考:https://redis.io/commands/?group=sorted_set

应用场景

  • 排行榜

    RScoredSortedSet<String> school = redissonClient.getScoredSortedSet("school");
    school.add(60, "tom");
    school.add(60, "jack");
    school.add(60, "tim");
    school.addScore("tom", 20);
    school.addScore("jack", 10);
    school.addScore("tim", 30);
    RFuture<Collection<ScoredEntry<String>>> collectionRFuture = school.entryRangeReversedAsync(0, -1);
    Iterator<ScoredEntry<String>> iterator = collectionRFuture.get().iterator();
    System.out.println("成绩从高到低排序");
    while(iterator.hasNext()) {
        ScoredEntry<String> next = iterator.next();
        String value = next.getValue();
        System.out.println(value);
    }
    RFuture<Collection<ScoredEntry<String>>> collectionRFuture1 = school.entryRangeReversedAsync(0, 2);
    Iterator<ScoredEntry<String>> iterator1 = collectionRFuture1.get().iterator();
    System.out.println("成绩前三名");
    while (iterator1.hasNext()) {
        System.out.println(iterator1.next().getValue());
    }
    

Bitmap

简单介绍

位图不是实际的数据类型,而是String类型中定义的一种面向位的操作,所以这个位图的最大存储量也是512M。可以容纳最少2^32不同的位,可以在不同的位置设置0或者1

常见命令

设置位的值

# 将位2设置为1
setbit permit 2 1

获取位的值

getbit permit 2

在这里插入图片描述

获取key的为1的个数

# 获取位为1的总数
bitcount permit

获取0或者1的第一位

# 获取key permit 位为1的第一个位置
bitpos permit 1

在这里插入图片描述

获取多个bitmap的位操作,比如&|

# 获取bkey和permit这两个的&运算,并且赋值给hbit
bitop AND hbit bkey permit

在这里插入图片描述

应用场景

  • 实时的数据统计

    比如:人员的考勤打卡记录,例如学生tom每次来上课就将相关的位记录位1

假如当月的第一天、第五天、第十天都来了

setbit tom 1 1
setbit tom 5 1
setbit tom 10 1

如何每月考勤,统计一下这个用户当月来了几天

bitcount tom 

也可以应用于统计一个网站一天有多少用户访问,例如用户ID为123、124、125的用户访问了csdn

setbit csdn:2023-11-08 123 1
setbit csdn:2023-11-08 124 1
setbit csdn:2023-11-08 125 1
...
# 统计一下当天的访问次数
bitcount csdn:2023-11-08 
  • 存储用户权限,比如用1来表示有权限,0表示没权限,使用位图可以节省很大的存储空间

附录

Redis命令查询网站:https://redis.io/commands/
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1185927.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于JavaWeb的网上销售系统设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

基于OCC+OSG集成框架下的GMSH之二阶网格划分探索

二阶网格相对于一阶网格&#xff0c;其计算节点数量更多&#xff0c;具体表现在一个一阶网格下的三角形中的每个边的中点构建一个点&#xff0c;对一阶三角形网格划分成四个三角形。gmsh提供了网格阶数设置&#xff0c;一般默认是一阶网格&#xff0c;本人根据gmsh文档&#xf…

To create the 45th Olympic logo by using CSS

You are required to create the 45th Olympic logo by using CSS. The logo is composed of five rings and three rectangles with rounded corners. The HTML code has been given. It is not allowed to add, edit, or delete any HTML elements. 私信完整源码 <!DOCT…

浅析Python数据处理的相关内容及要点

文章目录 前言一、Numpy1.Numpy属性2.Numpy创建3.Numpy运算4.Numpy索引5.Numpy其他 二、Pandas1.Pandas数据结构2.Pandas查看数据3.Pandas选择数据4.Pandas处理丢失数据5.Pandas合并数据6.Pandas导入导出 三、Matplotlib关于Python技术储备一、Python所有方向的学习路线二、Pyt…

单病种上报系统如何促进医院单病种质控管理

米软单病种上报系统自面市以来&#xff0c;一直以产品实力取胜&#xff0c;在助力医院实现病例数据快速、准确上报后&#xff0c;米软将自我优化重心投向了单病种医疗质量控制。 从填报过程监管&#xff0c;到结果分析、预警整改&#xff0c;米软重视质控的数据管理及应用。通过…

电机控制::理论分析::延迟环节对系统的影响

控制工程与理论 - 知乎 (zhihu.com) 浅论控制器的增益大小 (上) - 知乎 (zhihu.com) 浅论控制器的增益大小 (下) - 知乎 (zhihu.com) 延迟环节对控制系统的影响_延时环节的传递函数-CSDN博客

springboot 项目升级 2.7.16 踩坑

记录一下项目更新版本依赖踩坑 这个是项目最早的版本依赖 这里最初是最初是升级到 2.5.7 偷了个懒 这个版本的兼容性比较强 就选了这版本 也不用去修改就手动的去换了一下RabbitMQ的依赖 因为这边项目有AMQP 风险预警 1.spring-amqp版本低于2.4.17的用户应升级到2.4.17 2.spri…

C++ [继承]

本文已收录至《C语言和高级数据结构》专栏&#xff01; 作者&#xff1a;ARMCSKGT 继承 前言正文继承的概念及定义继承的概念继承的定义重定义 基类和派生类对象赋值转换派生类中的默认成员函数隐式调用显示调用 继承中的友元与静态成员友元静态成员 菱形继承概念 虚继承原理继…

C++|前言

c|前言 一、什么是C二、C发展史三、C的重要性3.1语言的使用广泛度3.2工作领域3.3校招领域 四、如何学习C4.1别人怎么学4.2自己怎么学 一、什么是C 在上回书已经学习了C语言&#xff0c;我们知道C语言是面向过程语言&#xff0c;C语言是结构化和模块化的语言&#xff0c;适合处理…

适合汽车音频系统的ADAU1977WBCPZ、ADAU1978WBCPZ、ADAU1979WBCPZ四通道 ADC,24-bit,音频

一、ADAU1977WBCPZ 集成诊断功能的四通道ADC&#xff0c;音频 24 b 192k IC&#xff0c;SPI 40LFCSP ADAU1977集成4个高性能模数转换器(ADC)&#xff0c;其直接耦合输入具有10 V rms性能。该ADC采用多位Σ-Δ架构&#xff0c;其连续时间前端能够实现低EMI性能。它可以直接连接…

vue3 开启 https

1、安装mkcert证书创建器 npm i mkcert -g 2、检验是否安装成功 mkcert --version 有版本好出现则成功 3、创建证书颁发机构 mkcert create-ca 会在当前目录生成&#xff0c;ca.crt 和 ca.key 两个文件 4、创建证书 mkcert create-cert 会在当前目录生成&#xff0c;…

ElementUI之el-progress动态修改进度条里面文本颜色与进度条色块统一

1.效果&#xff1a; 2.实现方式 通过行内style样式动态给整个progress赋颜色 再在样式里给进度条文字单独设置颜色为默认继承父级颜色就ok啦 <el-progress class"custom-progress" stroke-linecap"square" :style"{color:item.color}" :colo…

BAM(Bottleneck Attention Module)

BAM&#xff08;Bottleneck Attention Module&#xff09;是一种用于计算机视觉领域的深度学习模型结构&#xff0c;它旨在提高神经网络对图像的特征提取和感受野处理能力。BAM模块引入了通道注意力机制&#xff0c;能够自适应地加强或减弱不同通道的特征响应&#xff0c;从而提…

【斗破年番】彩鳞默认火火碰自己香肩,提其他女人,女王表示妒忌

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫资讯。 深度爆料&#xff0c;《斗破苍穹》年番国漫第69话最新剧情解析&#xff0c;主角萧炎来到了蛇人族的新部落。美杜莎是蛇人族的女王&#xff0c;她的威严和力量使她在族中拥有极高的地位。 在部落中&#xff0c…

通过创建自定义标签来扩展HTML

使用HTML时&#xff0c;例如&#xff0c;使用<b>标记显示粗体文本。 如果需要列表&#xff0c;则对每个列表项使用<ul>标记及其子标记<li> 。 标签由浏览器解释&#xff0c;并与CSS一起确定网页内容的显示方式以及部分内容的行为。 有时&#xff0c;仅使用一…

集合框架:Set集合的特点、HashSet集合的底层原理、哈希表、实现去重复

Set集合的特点 Set&#xff08;集合&#xff09;是一种无序的、不重复的数据结构&#xff0c;它的特点如下&#xff1a; 1. 集合中的元素是无序的&#xff1a;Set 中的元素没有顺序&#xff0c;无法通过索引来访问。 2. 集合中的元素是唯一的&#xff1a;Set 中不允许有重复…

SQL必知会(二)-SQL查询篇(1)-检索数据

第2课、检索数据 SELECT&#xff1a;查询 从一个或多个表中检索信息。 1&#xff09;检索单个列 需求&#xff1a;从 Products 表中查询所有行的产品名称。 SElECT prod_name FROM Products;输出结果&#xff1a; 2&#xff09;检索多个列 需求&#xff1a;从 Products 表…

Msa类处理多序列比对数据

同源搜索&#xff0c;多序列比对等都是常用的方式&#xff0c;但是有很多的软件可以实现这些同源搜索和多序列比对&#xff0c;但是不同的软件输出的文件格式却是不完全一致&#xff0c;有熟悉的FASTA格式的&#xff0c;也有A2M, A3M,stockholm等格式。 详细介绍&#xff1a; …

算法进阶指南图论 通信线路

通信线路 思路&#xff1a;我们考虑需要升级的那条电缆的花费&#xff0c;若其花费为 w &#xff0c;那么从 1 到 n 的路径上&#xff0c;至多存在 k 条路径的价值大于 w &#xff0c;这具有一定的单调性&#xff0c;当花费 w 越大&#xff0c;我们路径上价值大于 w 的花费会越…

Spring笔记(一)(黑马)(Ioc基础容器)

01、传统Javaweb开发的困惑 1.1 传统Javaweb开发困惑及解决方案 &#x1f616;问题一&#xff1a;层与层之间紧密耦合在了一起&#xff0c;接口与具体实现紧密耦合在了一起 解决思路&#xff1a;程序代码中不要手动new对象&#xff0c;第三方根据要求为程序提供需要的Bean对象…