【Redis篇】String类型命令详讲以及它的使用场景

目录

前言:

基本命令: 

 setnx/setxx

FLUSHALL 

mest

mget 

计数命令

INCR / INCRBY

 DECR/DECYBY

 INCRBYFLOAT

其他命令 

APPEND

GETRANGE

SETRANGE

STRLEN

String的典型使用场景

缓存(Cache)功能

计数(Counter)功能

共享会话(Session)

手机验证码功能


前言:

Redis 中的 String 类型是最基础的数据类型,同时也是最常用的。

一些基本命令上篇基本有讲,本篇对上篇未提到的命令进行补充

Redis的基本使用命令(GET,SET,KEYS,EXISTS,DEL,EXPIRE,TTL,TYPE)_php redis get exists-CSDN博客

特点

  • 二进制安全:Redis 的 String 可以存储任何数据,包括文字、数字、图片等二进制数据。
  • 最大长度:String 类型的值最大可以存储 512MB 的数据。
  • 多功能性:不仅能存储字符串,还能对数值型字符串执行一些操作。

 在redis中String三种内部编码形式,但他们都是属于String这个大类型中

  • 整数优先:当值为整数时,优先使用 int
  • 小字符串优先:当值为短字符串时,使用 embstr
  • 长字符串优先:当值为长字符串时,使用 raw
 

查看内部编码命令

OBJECT ENCODING KEY
127.0.0.1:6379> set key2 111
OK
127.0.0.1:6379> object encoding key2
"int"
127.0.0.1:6379> set key3 hhhh
OK
127.0.0.1:6379> object encoding key3
"embstr"
127.0.0.1:6379> set key4 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
OK
127.0.0.1:6379> object encoding key4
"raw"

基本命令: 

setnx/setxx

FLUSHALL 

清空所有的数据库  删库切忌  

类似 mysql中的 drop database 

mest

一次性设置多个 key 的值。

MSET key value [key value ...]
127.0.0.1:6379> mset key1 111 key2 hhhhh key3 ggggggggggg
OK
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
3) "key1"

mget 

一次性获取多个 key 的value值。

127.0.0.1:6379> mget key1 key2 key3
1) "111"
2) "hhhhh"
3) "ggggggggggg"

 mget   vs  多次 get

主要开销大就在网络开销 网络环境下一来一回很费时间,所以最后还是尽量一次弄完

操作时间
1000 次 get1000 x 1 + 1000 x 0.1 = 1100 毫秒
1 次 mget 1000 个键1 x 1 + 1000 x 0.1 = 101 毫秒

学会使用批量操作,可以有效提高业务处理效率,但是要注意,每次批量操作所发送的键的数量也不是无节制的,否则可能造成单⼀命令执行时间过长,导致 Redis 阻塞。

计数命令

INCR / INCRBY

将 key 对应的 string 表示的数字加⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。

127.0.0.1:6379> set key1 110
OK
127.0.0.1:6379> incr key1
(integer) 111
127.0.0.1:6379> set key2 22222222222222222222222222222222222222222222222
OK
127.0.0.1:6379> incr key2
(error) ERR value is not an integer or out of range
127.0.0.1:6379> incr key3
(integer) 1
127.0.0.1:6379> set key4 hhhhhhhhhhh
OK
127.0.0.1:6379> incr key4
(error) ERR value is not an integer or out of range
127.0.0.1:6379> keys *
1) "key4"
2) "key3"
3) "key2"
4) "key1"

可以看出:

1.如果是数字将会自增1

2.字符类型则直接报错

3.超过一定大小 也会报错

4.如果为设置key 自增key为默认从0+ 变成1

INCRBY

将 key 对应的 string 表⽰的数字加上对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。 语法:

INCRBY key decrement
127.0.0.1:6379> set key1 12
OK
127.0.0.1:6379> incrby key1 20
(integer) 32
127.0.0.1:6379> incrby key2 20
(integer) 20
127.0.0.1:6379> set key3 hh
OK
127.0.0.1:6379> incrby key3 20
(error) ERR value is not an integer or out of range

 DECR/DECYBY

 DECR:

将 key 对应的 string 表⽰的数字减⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
 

127.0.0.1:6379> set key1 10
OK
127.0.0.1:6379> decr key1
(integer) 9
127.0.0.1:6379> decr key2
(integer) -1

 DECYBY:

将 key 对应的 string 表⽰的数字减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。语法:

DECRBY key decrement
127.0.0.1:6379> decrby key1 10
(integer) -10
127.0.0.1:6379> set key2 100
OK
127.0.0.1:6379> decrby key2 50
(integer) 50

 INCRBYFLOAT

将 key 对应的 string 表示的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的不是 string,或者不是⼀个浮点数,则报错。允许采用科学计数法表示浮点数。

127.0.0.1:6379> set key1 1.5
OK
127.0.0.1:6379> incr key1
(error) ERR value is not an integer or out of range
127.0.0.1:6379> decr key1
(error) ERR value is not an integer or out of range
127.0.0.1:6379> incrbyfloat key1 10
"11.5"
127.0.0.1:6379> incrbyfloat key1 -5
"6.5"
127.0.0.1:6379> incrbyfloat key2 -1.0
"-1"
127.0.0.1:6379> incrbyfloat key3 5
"5"
127.0.0.1:6379> incr key3 
(integer) 6

1.float类型redis并没有单独存放 使用incr or decr 都会出错 只能使用incrbyfloat

2.也是可以对未定义的key进行增减

其他命令 

APPEND

如果 key 已经存在并且是⼀个 string,命令会将 value 追加到原有 string 的后边。如果 key 不存在,则效果等同于 SET 命令。 

类似java中的StringBuffer/StringBuilder 中的append命令效果类似 

语法:

APPEND KEY VALUE
127.0.0.1:6379> set key1 hello
OK
127.0.0.1:6379> append key1 redis
(integer) 10
127.0.0.1:6379> get key1
"helloredis"
127.0.0.1:6379> append key2 hi!
(integer) 3
127.0.0.1:6379> get key2
"hi!"
127.0.0.1:6379> append key2 世界
(integer) 9
127.0.0.1:6379> get key2
"hi!\xe4\xb8\x96\xe7\x95\x8c"

1.返回的结果为字节个数

2.在未设置key的情况下 append追加可以有set的功能

2.如果是中文字符 在redis一个中文字符占3个字节 所以可以看见3+6为9个字节在key2中

GETRANGE

返回 key 对应的 string 的子串,由 start 和 end 确定(左闭右闭)。可以使用负数表示倒数。-1 代表倒数第⼀个字符,-2 代表倒数第二个,其他的与此类似。超过范围的偏移量会根据 string 的长度调整成正确的值。 遵循(左闭右闭)的原则

127.0.0.1:6379> set key1 helloworld
OK
127.0.0.1:6379> getrange key1 0 4
"hello"
127.0.0.1:6379> getrange key1 0 -1
"helloworld"
127.0.0.1:6379> getrange key1 -1 0
""
127.0.0.1:6379> getrange key1 1 -2
"elloworl"
127.0.0.1:6379> getrange key2 0 1
""

SETRANGE

覆盖字符串的一部分,从指定的偏移开始。语法:

SETRANGE key
127.0.0.1:6379> set key1 "hello world"
OK
127.0.0.1:6379> setrange key1 6 redis
(integer) 11
127.0.0.1:6379> get key1
"hello redis"
127.0.0.1:6379> setrange key2 2 hh
(integer) 4
127.0.0.1:6379> get key2
"\x00\x00hh"
127.0.0.1:6379> set key3 helloworld
OK
127.0.0.1:6379> setrange key3 4 reids
(integer) 10
127.0.0.1:6379> get key3
"hellreidsd"

1.未设置的key 使用setrange可以直接设置 并且偏移量前的字符都为0

STRLEN

获取 key 对应的 string 的长度。当 key 存放的类似不是 string 时,报错。语法:

STRLEN key
127.0.0.1:6379> set key1 hello
OK
127.0.0.1:6379> strlen key1
(integer) 5
127.0.0.1:6379> strlen key2
(integer) 0
127.0.0.1:6379> lpush key3 11 22 33 44 
(integer) 4
127.0.0.1:6379> strlen key3
(error) WRONGTYPE Operation against a key holding the wrong kind of value

字符串类型命令小结:

命令执⾏效果时间复杂度
set key value [key value...]设置 key 的值是 valueO(k), k 是键个数
get key获取 key 的值O(1)
del key [key ...]删除指定的 keyO(k), k 是键个数
mset key value [key value ...]批量设置指定的 key 和 valueO(k), k 是键个数
mget key [key ...]批量获取 key 的值O(k), k 是键个数
incr key指定的 key 的值 +1O(1)
decr key指定的 key 的值 -1O(1)
incrby key n指定的 key 的值 +nO(1)
decrby key n指定的 key 的值 -nO(1)
incrbyfloat key n指定的 key 的值 +nO(1)
append key value指定的 key 的值追加 valueO(1)
strlen key获取指定 key 的值的⻓度O(1)
setrange key offset value覆盖指定 key 的从 offset 开始的部分值O(n),n 是字符串⻓度, 通常视为 O(1)
getrange key start end获取指定 key 的从 start 到 end 的部分值O(n),n 是字符串⻓度, 通常视为 O(1)

String的典型使用场景

缓存(Cache)功能

其中 Redis 作为缓冲层,MySQL 作为存储层,绝⼤部分请求的数据都是从 Redis 中获取。由于 Redis 具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。

Redis + MySQL 组成的缓存存储架构 

下面一个详细案例抽奖系统:查询活动详细信息的内容

根据活动Id去redis查找 

如果没有 只能去Mysql对应的表中查找 

查找到相应的表之后,再返回结果 并且缓存到redis中 方便下一次查找

 @Override
    public ActivityDetailDTO getActivityDetail(Long activityId) {
        if(null == activityId) {
            logger.warn("获取活动详细信息失败!");
            return null;
        }
        //查询redis
        ActivityDetailDTO activityDetailDTO = getActivityFromCache(activityId);
        if(null != activityDetailDTO) {
            return activityDetailDTO;
        }
        //如果redis不存在 查表
        //活动表
        ActivityDO aDO = activityMapper.selectById(activityId);
        //活动人员表
        List<ActivityUserDO> auDO = activityUserMapper.selectByActivityId(activityId);
        //活动奖品表
        List<ActivityPrizeDO> apDO = activityPrizeMapper.selectByActivityId(activityId);
        //奖品表
        List<Long> prizeIds = apDO.stream()
                .map(ActivityPrizeDO::getPrizeId)
                .collect(Collectors.toList());
        List<PrizeDO> pDO = prizeMapper.batchSelectByIds(prizeIds);
        //重新整合到redis中
        activityDetailDTO = convertToActivityDetailDTO(aDO,apDO,pDO,auDO);
        cacheActivityDetailDTO(activityDetailDTO);
        //返回
        return activityDetailDTO;
    }

计数(Counter)功能

许多应用都会使用 Redis 作为计数的基础⼯具,它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源。如图所示,例如视频网站的视频播放次数可以使⽤ Redis 来完成:用户每播放⼀次视频,相应的视频播放数就会自增 1。

共享会话(Session)

假设一个病人(cookie)(客户端)去找医生(小绿)(session)(服务器)看病 ,看完之后,过一个礼拜回来复查

一个礼拜后,病人去找医生复查,可以恰巧不幸的是此时医生(小绿)不是上一个看病的医生,而是另外一个医生(小红),此时俩个不同的医生,并不知道病人的状态如何

所以医院的正确是:使用一套系统,记录病人的病例,即使在不同的医生的情况下,也可以找到当时的病人的情况

使用 Redis 将用户的 Session 信息进⾏集中管理,如图所示,在这种模式下,只要保证 Redis 是高可用和可扩展性的,无论用户被均衡到哪台 Web 服务器上,都集中从 Redis 中查询、更新 Session 信息。

手机验证码功能

很多应用出于安全考虑,会在每次进行登录时,让用户输人手机号并且配合给手机发送验证码,然后让用户再次输⼊收到的验证码并进⾏验证,从而确定是否是用户本人。为了短信接口不会频繁访问,会限制用户每分钟获取验证码的频率,例如⼀分钟不能超过 5 次

并且可以设置手机验证码有效时间 过期了将不能使用

 下面是设置缓存过期时间的代码:

    public void sendVerificationCode(String phoneNumber) {
        //校验手机号
        if(!RegexUtil.checkMobile(phoneNumber)) {
            throw new ServiceException(ServiceErrorCodeConstants.PHONE_NUMBER_ERROR);
        }
        //生成随机验证码
        String code = CaptchaUtil.getCaptcha(4);
        //发送验证码
        Map<String,String> map = new HashMap<>();
        map.put("code",code);

        smsUtil.sendMessage(VERIFICATION_CODE_TEMPLATE_CODE,
                phoneNumber,
                JacksonUtils.writeValueString(map));

        //缓存验证码
        redisUtil.set(VERIFICATION_CODE_PREFIX + phoneNumber,code,VERIFICATION_CODE_TIMEOUT);
    }

 以上介绍了使用 Redis 的字符串数据类型可以使用户的几个场景,但其适用场景远不止于此,开发人员可以结合字符串类型的特点以及提供的命令,充分发挥自己的想象力,在自己的业务中去找到合适的场景去使用 Redis 的字符串类型。


结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!  

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【2024】前端学习笔记19-ref和reactive使用

学习笔记 1.ref2.reactive3.总结 1.ref ref是 Vue 3 中用来创建响应式引用的一个函数&#xff0c;通常用于基本数据类型&#xff08;如字符串、数字、布尔值等&#xff09;或对象/数组的单一值。 ref特点&#xff1a; ref 可以用来创建单个响应式对象对于 ref 包裹的值&…

构造函数的相关

文章目录 一、构造函数 今天我们要来讲解类的默认成员函数之一的构造函数。 一、构造函数 构造函数是特殊的成员函数&#xff0c;需要注意的是&#xff0c;构造函数虽然名称叫构造&#xff0c;但是构造函数的主要任务并不是开空间创建对象(我们常使用的局部对象是栈帧创建时&…

C嘎嘎探索篇:栈与队列的交响:C++中的结构艺术

C嘎嘎探索篇&#xff1a;栈与队列的交响&#xff1a;C中的结构艺术 前言&#xff1a; 小编在之前刚完成了C中栈和队列&#xff08;stack和queue&#xff09;的讲解&#xff0c;忘记的小伙伴可以去我上一篇文章看一眼的&#xff0c;今天小编将会带领大家吹奏栈和队列的交响&am…

Xcode15(iOS17.4)打包的项目在 iOS12 系统上启动崩溃

0x00 启动崩溃 崩溃日志&#xff0c;只有 2 行&#xff0c;看不出啥来。 0x01 默认配置 由于我开发时&#xff0c;使用的 Xcode 14.1&#xff0c;打包在另外一台电脑 Xcode 15.3 Xcode 14.1 Build Settings -> Asset Catalog Compliter - Options Xcode 15.3 Build S…

【Python爬虫实战】深入解析 Scrapy:从阻塞与非阻塞到高效爬取的实战指南

&#x1f308;个人主页&#xff1a;易辰君-CSDN博客 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、阻塞和非阻塞 &#xff08;一&#xff09;阻塞 &#xff08;二&#xff09;非阻塞 二、Scrapy的工作…

01 [51单片机 PROTEUS仿真设计]基于温度传感器的恒温控制系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 五个按键&#xff0c;分别为启动按键&#xff0c;则LCD1602显示倒计时&#xff0c;音乐播放 设置按键&#xff0c;可以设置倒计时的分秒&#xff0c;然后加减按键&#xff0c;还有最后一个暂停音乐…

途普科技企业知识中台完成华为昇思MindSpore技术认证

近日&#xff0c;北京途普科技有限公司&#xff08;以下简称“途普科技”&#xff09;作为华为昇腾大模型方向的应用软件伙伴&#xff0c;核心产品企业知识中台已成功与华为AI框架昇思MindSpore完成相互兼容性认证。这一成就标志着途普科技在AI领域与华为的合作进一步加深&…

shodan(7)

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

MYSQL 表的增删改查(上)

目录 1.新增数据 2.查询数据 一般查询 去重查询 排序查询 关于NULL 条件查询 分页查询 1.新增数据 语法&#xff1a;insert into 表名[(字段1&#xff0c;字段2...)] values (值&#xff0c;值....); 插入一条新数据行&#xff0c;前面指定的列&#xff0c;要与后面v…

海康面阵、线阵、读码器及3D相机接线说明

为帮助用户快速了解和配置海康系列设备的接线方式&#xff0c;本文将针对海康面阵相机、线阵相机、读码器和3D相机的主要接口及接线方法进行全面整理和说明。 一、海康面阵相机接线说明 海康面阵相机使用6-pin P7接口&#xff0c;其功能设计包括电源输入、光耦隔离信号输入输出…

Java多线程八股(三)一>多线程环境使用哈希表和ArrayList

目录&#xff1a; 一.多线程环境使用ArrayList&#xff1a; 二.多线程使用哈希表&#xff1a; 一.多线程环境使用ArrayList&#xff1a; 首先我们知道&#xff0c;Vector, Stack, HashTable, 是线程安全的(但是不建议用), 其他的集合类不是线程安全的 &#xff0c;下面是…

TCP IP协议和网络安全

传输层的两个协议&#xff1a; 可靠传输 TCP 分段传输 建立对话&#xff08;消耗系统资源&#xff09; 丢失重传netstat -n 不可靠传输 UDP 一个数据包就能表达完整的意思或屏幕广播 应用层协议&#xff08;默认端口&#xff09;&#xff1a; httpTCP80 网页 ftpTCP21验证用户身…

Webpack前端工程化进阶系列(二) —— HMR热模块更新(图文+代码)

前言 之前更新过一篇Webpack文章:Webpack入门只看这一篇就够了(图文代码)&#xff0c;没想到颇受好评&#xff0c;很快就阅读量就破万了hhh&#xff0c;应读者私信的要求&#xff0c;决定继续更新Webpack进阶系列的文章&#xff01; 进入今天的主题 —— HMR 热模块替换(HotM…

第三讲 架构详解:“隐语”可信隐私计算开源框架

目录 隐语架构 隐语架构拆解 产品层 算法层 计算层 资源层 互联互通 跨域管控 本文主要是记录参加隐语开源社区推出的第四期隐私计算实训营学习到的相关内容。 隐语架构 隐语架构拆解 产品层 产品定位&#xff1a; 通过可视化产品&#xff0c;降低终端用户的体验和演…

C# 结构体

文章目录 前言一、结构体的定义与基本使用&#xff08;一&#xff09;定义结构体&#xff08;二&#xff09;结构体的使用示例 二、C# 结构的特点&#xff08;一&#xff09;丰富的成员类型&#xff08;二&#xff09;构造函数相关限制与特性&#xff08;三&#xff09;继承方面…

Easyexcel(7-自定义样式)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09;Easyexcel&#xff08;5-自定义列宽&#xff09;Easyexcel&#xff08;6-单…

【c语言】文件操作详解 - 从打开到关闭

文章目录 1. 为什么使用文件&#xff1f;2. 什么是文件&#xff1f;3. 如何标识文件&#xff1f;4. 二进制文件和文本文件&#xff1f;5. 文件的打开和关闭5.1 流和标准流5.1.1 流5.1.2 标准流 5.2 文件指针5.3 文件的打开和关闭 6. 文件的读写顺序6.1 顺序读写函数6.2 对比一组…

2024-11-23 队列及顺序存储实现

2.3.1 队列及顺序存储实现 与堆栈类似&#xff0c;队列也是一种受限制的线性表。 其实我们在日常生活中经常会碰到排队。我们来观察一下&#xff0c;什么叫做队列&#xff0c;里面有两个最基本的操作&#xff0c;一个叫做入队&#xff0c;一个叫做出队。也就是你能加入这个队…

卷积神经网络学习记录

目录 神经网络基础定义&#xff1a; 基本组成部分 工作流程 卷积层&#xff08;卷积定义&#xff09;【CONV】&#xff1a; 卷积层&#xff08;Convolutional Layer&#xff09; 特征提取&#xff1a;卷积层的主要作用是通过卷积核&#xff08;或滤波器&#xff09;运算提…

数据结构初阶---复杂度

一、数据结构前言 1.数据结构与算法 数据结构(Data Structure)&#xff1a;是计算机组织、存储数据的一种方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。 算法(Algorithm)&#xff1a;就是定义良好的计算过程&#xff0c;他取一个或一组的值为输入&am…