[Redis] Redis中的String类型

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
🎃Redis(96平均质量分)https://blog.csdn.net/2301_80050796/category_12777129.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
在这里插入图片描述

目录

  • 1. Redis中的String的相关操作
    • 1.1 字符串的存储方式
    • 1.2 关于string的常见命令
    • 1.3 string的其他命令
    • 1.4 字符串指令小结
  • 2. String的内部编码方式
  • 3. string类型的具体应用场景
    • 3.1 缓存功能
    • 3.2 计数功能
    • 3.3 共享会话(session)
    • 3.4 手机验证码

1. Redis中的String的相关操作

1.1 字符串的存储方式

Redis中,key的数据类型是一个string,但是value的数据结构可以是多种多样的,我们在之前的文章中介绍过.这里不再赘述.
这里我们需要注意的是.Redis中存储string的方法和java中,MySQL中的存储方式并不一样.Redis中存储字符串的时候,会直接存储字符串的二进制数据,不会对二进制数据做出任何的编码转换,存入的是什么,取出的还是什么,但是java和MySQL不一样,java中存储字符串的时候会涉及到编码方式的问题,MySQL中,字段不可以插入中文,这是因为MySQL的默认编码方式是拉丁文,与汉字不兼容.
既然Redis中可以存储二进制数据,那么就不仅仅可以存储字符串,还可以存储一些其他的二进制数据,比如图片,视频,音频等.
但是Redis是单线程的,Redis为了保证存储于获取数据的高效性,一般不可以存储占据空间太大的数据,默认情况下是不超过512M.
在这里插入图片描述

1.2 关于string的常见命令

  • set
    在前面的章节,我们曾经介绍过set这个命令,但是之前的哪个set命令还不是最全面的,set除了可以设置键值对之外,还可以对键值对设置其他的属性.
    set key value [ex seconds|px milliseconds] [nx|xx]
    • 其中ex是为当前键值对设置过期时间,单位是秒,相当于set key value; expire key seconds,也可以使用px设置毫秒级别的过期时间.
    • nx是当前如果当前key存在,则不设置当前的key,直接返回nil,如果不存在,则设置,而xx与nx的效果恰好相反,当key存在的时候,覆盖掉当前的key,如果当前key不存在,则不设置.
  1. 夹带选项的set指令可以被后续的Redis命令取代,比如setex,setnx,setpx等.
  2. 如果使用xx选项,可能会改变原来value的数据类型,原来key的过期时间也会被覆盖掉
  3. 原地离职小技巧: 如果想要删除Redis服务器中的所有键值对,可以使用flushall指令.

代码演示:

127.0.0.1:6379> set key1 value1 ex 10
OK
127.0.0.1:6379> ttl key1
(integer) 6
127.0.0.1:6379> ttl key1
(integer) 5
127.0.0.1:6379> ttl key1
(integer) 2
127.0.0.1:6379> ttl key1
(integer) -2
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> set key1 value2 nx
(nil)
127.0.0.1:6379> set key1 value2 xx
OK
127.0.0.1:6379> get key1
"value2"
127.0.0.1:6379> set key2 value1 ex 20
OK
127.0.0.1:6379> set key2 value3 xx
OK
127.0.0.1:6379> ttl key2
(integer) -1 //覆盖掉了原来的过期时间
  • get
    这个指令和我们之前提到过的get指令没有什么区别,==唯一需要注意的一点就是,获取key对应的value的时候,value必须是string类型的数据,否则就会报错.
127.0.0.1:6379> lpush key val1 val2 val3
(integer) 3
127.0.0.1:6379> get key
(error) WRONGTYPE Operation against a key holding the wrong kind of value

这里我们创建了一个value为列表的键值对,我们发现在用get访问的时候,程序出现了报错.

  • mset
    用来一次性设置多个键值对.
127.0.0.1:6379> mset key1 val1 key2 val2 key3 val3
OK
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
3) "key3"
  • mget
    用来一次性获取多个key对应的value.
127.0.0.1:6379> mget key1 key2 key3
1) "val1"
2) "val2"
3) "val3"

我们在前面的章节的exists指令提到过,我们能把多次查询合并到一步,我们一般不会使用分开好几步的查询.这样一方面会比较占用网络资源,另一方面会让网络请求拖慢Redis的执行性能.
在这里插入图片描述
在这里插入图片描述
但是我们使用上面两个请求的时候,也不可以一次性设置太多的key和value或者是一次性获取太多的value.否则就会让Redis服务器发生阻塞.

  • setnx
    set key value nx效果一样.key存在的时候不创建,不存在的时候才创建.
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
3) "key3"
127.0.0.1:6379> setnx key1 value1
(integer) 0
127.0.0.1:6379> get key1
"val1"
  • setex
    setex key seconds valueset key value ex seconds效果一样.为键值对设置过期时间.这里要注意一下setex的语法格式,先写key,再写过期时间,再写value.
127.0.0.1:6379> setex key4 10 value4
OK
127.0.0.1:6379> ttl key4
(integer) 5
127.0.0.1:6379> ttl key4
(integer) 4
127.0.0.1:6379> ttl key4
(integer) 2
127.0.0.1:6379> ttl key4
(integer) 0
127.0.0.1:6379> ttl key4
(integer) -2
  • incr
    incr key
    针对某一个key的value+1.如果这个key的value不是64位的整型,则报错.如果这个key不存在的话,则创建这个key,其中value的值默认为0,之后对value+1.这个操作的返回值就是这个key的value+1之后的值.
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> incr key1
(integer) 2
127.0.0.1:6379> incr key2 
(integer) 1
127.0.0.1:6379> mget key1 key2
1) "2"
2) "1"
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> incr key1
(error) ERR value is not an integer or out of range
  • incrby
    incrby key increament
    针对某个key的value+指定的值.如果这个key的value不是64位的整型,则报错.如果这个key不存在的话,则创建这个key,其中value的值默认为0,之后对value+指定值.这个操作的返回值就是这个key的value+指定值之后的值.
127.0.0.1:6379> mget key1 key2
1) "2"
2) "1"
127.0.0.1:6379> incrby key2 7
(integer) 8
127.0.0.1:6379> incrby key1 2
(error) ERR value is not an integer or out of range
  • decr
    decr key
    针对某一个key的value-1.如果这个key的value不是64位的整型,则报错.如果这个key不存在的话,则创建这个key,其中value的值默认为0,之后对value-1.这个操作的返回值就是这个key的value-1之后的值.
127.0.0.1:6379> incrby key2 7
(integer) 8
127.0.0.1:6379> decr key2 
(integer) 7
127.0.0.1:6379> decr key3
(integer) -1
127.0.0.1:6379> get key3
"-1"
127.0.0.1:6379> decr key1 
(error) ERR value is not an integer or out of range
  • decrby
    decrby key decreament
    针对某个key的value-指定的值.如果这个key的value不是64位的整型,则报错.如果这个key不存在的话,则创建这个key,其中value的值默认为0,之后对value-指定值.这个操作的返回值就是这个key的value-指定值之后的值.
127.0.0.1:6379> decrby key2 1
(integer) 6
127.0.0.1:6379> decrby key4 3
(integer) -3
127.0.0.1:6379> decrby key1 2
(error) ERR value is not an integer or out of range
  • incrbyfloat
    incrbyfloat key increament
    将key对应的string表示的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值如果key不存在,则视为key对应的value是0。如果key对应的不是一个浮点数(或整数),则报错。允许采用科学计数法表示浮点数.
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> INCRBYFLOAT key1 0.5
"1.5"
127.0.0.1:6379> set key2 value2
OK
127.0.0.1:6379> INCRBYFLOAT key2 0.5
(error) ERR value is not a valid float
127.0.0.1:6379> INCRBYFLOAT key1 -0.7
"0.8"
127.0.0.1:6379> INCRBYFLOAT key -0.5
"-0.5"

[注意] 这里的小数,Redis在保存的时候,在底层实际保存的是embstr,在Redis中并没有浮点型这样的数据类型.

127.0.0.1:6379> object encoding key1
"embstr"

1.3 string的其他命令

  • append
    append key value
    给指定key对应value拼接一个字符串,如果key已经存在,需要保证key对应的value是一个string类型的.如果这个key不存在,效果相当于set.
127.0.0.1:6379> append key2 aaaaa
(integer) 11
127.0.0.1:6379> get key2
"value2aaaaa"
127.0.0.1:6379> append key3 bbbbb
(integer) 5
127.0.0.1:6379> get key3
"bbbbb"
127.0.0.1:6379> append key1 ccccc
(integer) 8
127.0.0.1:6379> get key1
"0.8ccccc"
127.0.0.1:6379> set key4 7
OK
127.0.0.1:6379> append key4 ccccc
(integer) 6
127.0.0.1:6379> get key4
"7ccccc"

[注意]

  1. 当key对应的value保存的是一个整数,或者是一个小数的时候,别看是一个数字,实际Redis在保存他们的时候,同样是把他们当做字符串来看待的.
  2. 这里append的返回值是增加后的字符串的字节数,而不是字符数,下面我们使用汉字来说明一下这个问题.
127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> set key1 你好
OK
127.0.0.1:6379> get key1
"\xe4\xbd\xa0\xe5\xa5\xbd"

这里我们看到Redis在保存汉字的时候,是已汉字的二进制方式来保存的,这也印证了我们上面所提到的,Redis保存string的时候,没有经过字符串编码,而是直接保存二进制数据."你好"两个汉字是6个字节.

127.0.0.1:6379> append key1 你好
(integer) 12

我们在原来字符串的基础上又一次拼接了一个"你好".返回的字符串长度是12字节.
那么如何让Redis显示汉字而不是汉字的16进制编码呢?我们可以在启动Redis的时候,使用redis-cil --raw指令来打开redis.

root@iZ2zeh2c69p4ax5heci8wmZ:~# redis-cli --raw
127.0.0.1:6379> get key1
你好你好
  • getrange
    getrange key start end
    在指定key的[start,end]区间(两边都是闭区间),截取一段字符串.有点像java中的substring()方法.
    其中redis的getrange操作与python一样是支持负数下标的,其中-1表示倒数第一个字符串.-2表示倒数第二个字符串.
127.0.0.1:6379> set key2 helloworld
OK
127.0.0.1:6379> getrange key2 0 -1
"helloworld"
127.0.0.1:6379> getrange key2 1 4
"ello"

[注意]
这里截取的时候,start和end依然指的是字节数.所以这里我们不建议使用getrange命令来截取汉字.因为汉字是汉字编码的16进制存储的,如果我们的redis是以–raw的方式打开的,截取出来的汉字很可能是一堆乱七八糟的东西.

127.0.0.1:6379> get key2
你好
127.0.0.1:6379> GETRANGE key2 1 -2
½ 
  • setrange
    setrange key offset value
    将指定key从第offset(这个叫做偏移量,MySQL中也有这个字段)字节开始的地方设置为指定字符串.返回设置之后字符串的长度.
127.0.0.1:6379> set key3 value
OK
127.0.0.1:6379> setrange key3 2 aaaaaaaa
10
127.0.0.1:6379> get key3
vaaaaaaaaa
  • strlen
    strlen key
    获取指定key对应value的字节长度.
127.0.0.1:6379> get key3
vaaaaaaaaa
127.0.0.1:6379> get key2
你好
127.0.0.1:6379> strlen key2
6
127.0.0.1:6379> strlen key3
10

1.4 字符串指令小结

在这里插入图片描述

2. String的内部编码方式

这个话题我们在上一篇文章中提到过

  • raw
    这个是最基本的字符串,类似与Java中的byte[ ]数组.
  • int
    redis有时会实现一些计数的功能,当value是整数的时候,redis就会直接用int类型来保存.
  • embstr
    当字符串比较短的时候,redis就会把字符串优化为embstr.

有的资料上会写当字符串超过39字节的时候会转换为raw,在39字节以下时候,就是embstr,这里不建议大家去记忆这样具体的数字,因为这个是可以根据具体的业务场景来修改的.

3. string类型的具体应用场景

3.1 缓存功能

其中Redis作为缓冲层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用
在这里插入图片描述
具体流程:
在应用服务器访问数据的时候,首先访问的是缓存(redis)的数据,如果redis中存在对应的数据,则返回给应用服务器.如果redis中不存在,则去存储层查询(MySQL),如果存在,则返回给应用服务器,同时保存在缓存(redis)中.如果MySQL中也不存在,直接给应用服务器返回错误码.
上述的过程存在一个明显的问题,就是在这种情况下,redis的数据会越积越多.针对这种情况,redis会给其中的一些键值对设置过期时间,也在内存不足的情况下提供了内存淘汰的策略.

3.2 计数功能

许多应用都会使用Redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源.
假如我们需要统计一个视频的播放次数,如果直接对MySQL中的数据进行操作的话,开销会非常大,这时候我们就引入了redis来帮我们计数.但是如果直接使用redis来统计数据的话,这也不是redis擅长的领域,统计的工作还是需要交给MySQL来做.所以在这个过程中redis和MySQL是相辅相成的.
在这里插入图片描述
在一个视频被播放的时候.redis就会给对应的视频id的播放次数+1,之后会异步同步到统计数据仓库中,这里的异步同步指的是,数据不是立即同步过去的,而是每隔一段时间对数据进行同步,这样会在某种程度上减小统计数据仓库的开销.

实际中要开发⼀个成熟、稳定的真实计数系统,要⾯临的挑战远不⽌如此简单:防作弊、按照不同维度计数、避免单点问题、数据持久化到底层数据源等

3.3 共享会话(session)

我们在实际开发的过程中,系统可能是分布式的,一个系统可能会有多台服务器.在用户访问一个应用的不同板块的时候,可能会访问到不同的服务器,这时候不是每一个服务器都保存着这个用户session.如果在用户访问其他服务器的时候,就需要用户重新登录.我们如果对session采用分散存储的方式:
在这里插入图片描述
如果我们在上述方案的基础上引入redis.redis就可以对用户的session数据进行集中统一管理.这种情况下,无论用户被均衡到哪台Web服务器上,都集中从Redis中查询、更新Session信息.
在这里插入图片描述

3.4 手机验证码

用户在登录的时候,为了保证用户账号的安全,我们会使用验证码.当用户登录的时候,redis就会在服务器中保存一个与用户对应的验证码,这个验证码具有过期时间(比如在5分钟内有效).在用户输入验证码之后,会从redis中查询对应的键值对,校验用户的验证码.
当然为了用户反复接收验证码,导致redis压力过大,一般规定在一分钟之内,最多接收一次验证码,如果手机没有验证码,可以尝试在一分钟之后重新获取验证码.
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑开机速度慢怎么解决?

电脑开机速度慢怎么解决?电脑开机速度慢的原因可以是多方面的,以下是一些常见的原因: 启动项过多: 许多软件在系统启动时会自动启动,导致启动项过多,从而延长了开机时间。过时的驱动程序: 设备…

《基于深度半监督学习的目标检测综述》泛读

基于深度半监督学习的目标检测方法分为 1、生成式方法 2、一致性正则化方法 3、基于图的方法 4、伪标记方法和混合方法 然后基于常用数据集 对典型方法进行了性能对比,最后分析了其挑战和发展趋势,旨在为相关研究提供参考 收获就是: 1…

网络学习-eNSP配置NAT

NAT实现内网和外网互通 #给路由器接口设置IP地址模拟实验环境 <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]undo info-center enable Info: Information center is disabled. [Huawei]interface gigabitethernet 0/0/0 [Huawei-Gigabi…

计算机网络八股总结

这里写目录标题 网络模型划分&#xff08;五层和七层&#xff09;及每一层的功能五层网络模型七层网络模型&#xff08;OSI模型&#xff09; 三次握手和四次挥手具体过程及原因三次握手四次挥手 TCP/IP协议组成UDP协议与TCP/IP协议的区别Http协议相关知识网络地址&#xff0c;子…

Qt Model/View概述

概述 Qt包含了一组item view类&#xff0c;它们使用模型/视图架构来管理数据之间的关系以及呈现给用户的方式。该体系结构引入的功能分离为开发人员提供了更大的灵活性来定制项目的表示&#xff0c;并提供了一个标准的模型接口&#xff0c;以允许广泛的数据源与现有项目视图一…

独立站新纪元:破局而出,共绘可持续发展蓝图

随着全球电商市场的日益繁荣与平台竞争的加剧,独立站作为商家自主掌控品牌与市场的桥头堡,正面临着前所未有的挑战与机遇。在这个瞬息万变的时代,如何在平台垄断的阴影下突围而出,实现可持续增长,成为了每一位独立站商家亟需解答的课题。为此,店匠科技( Shoplazza ) 将于 9月 2…

【MySQL】查询表中重复数据、模糊查询列信息、快速copy表数据(1)

一、SQL查询重复的数据&#xff1a; 1、SQL格式&#xff1a; Select * From 数据表 Where 重复记录字段 in ( select 重复记录字段 From 数据表 Group By 重复记录字段 Having Count(重复记录字段)>1) 2、举例&#xff1a; 在这个patient_member_info表中&#xff0c;我们…

【Hot100】LeetCode—62. 不同路径

目录 1- 思路题目识别动规五部曲 2- 实现⭐62. 不同路径——题解思路 3- ACM 实现 原题链接&#xff1a;62. 不同路径 1- 思路 题目识别 识别1 &#xff1a;给一个二维矩阵&#xff0c;每次只能向下或者向右移动一步识别2&#xff1a;求解到达最右下角的路径数。 动规五部曲…

编写XBOX控制器实现鼠标键盘输入

1.核心部分, XINPUT输入封装 XInput封装https://mp.csdn.net/mp_blog/creation/editor/1420701282.对话框窗口编写 Win32 对话框封装-CSDN博客https://blog.csdn.net/Flame_Cyclone/article/details/142110008?spm1001.2014.3001.5501 3.使用到的其他封装 字符串编码转换与…

灰色关联度/模糊聚类/最邻近算法KNN/随机森林RF/极限学习机

一、灰色关联度 简介&#xff1a; 对于两个系统之间的因素&#xff0c;其随时间或不同对象而变化的关联性大小的量度&#xff0c;称为关联度。在系统发展过程中&#xff0c;若两个因素变化的趋势具有一致性&#xff0c;即同步变化程度较高&#xff0c;即可谓二者关联程度较高…

【C++】认识C++(前言)

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:C_小米里的大麦的博客-CSDN博客 &#x1f381;代码托管:C: 探索C编程精髓&#xff0c;打造高效代码仓库 (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 一、本节概述 二、什么是C 三、C发展史 四…

Python画笔案例-044 绘制四米围方

1、绘制 四米围方 通过 python 的turtle 库绘制 四米围方&#xff0c;如下图&#xff1a; 2、实现代码 绘制 四米围方&#xff0c;以下为实现代码&#xff1a; """四米围方.py """ import turtledef draw_mi():"""画米字图形&qu…

关于武汉芯景科技有限公司的IIC缓冲器芯片XJ4307开发指南(兼容LTC4307)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、功能描述 1.总线超时&#xff0c;自动断开连接 当 SDAOUT 或 SCLOUT 为低电平时&#xff0c;将启动内部定时器。定时器仅在相应输入变为高电平时重置。如果在 30ms &#xff08;典型值&#xff09; 内没有变为高…

开展文化创新与传承 全球老子圣像评选启动

9月11日&#xff0c;在刚见证了中华社会文化发展基金会老子文化公益基金成立发布会盛典的中华文化园&#xff0c;又迎来了中华社会文化发展基金会领导的亲临指导。本次指导由中华社会文化发展基金会执行副秘书长蒋晔带队&#xff0c;魏欣主任和高凯主任同行&#xff0c;共同考察…

JMeter脚本开发

环境部署 Ubuntu系统 切换到root用户 sudo su 安装上传下载的命令 apt install lrzsz 切换文件目录 cd / 创建文件目录 mkdir java 切换到Java文件夹下 cd java 输入rz回车 选择jdk Linux文件上传 解压安装包 tar -zxvf jdktab键 新建数据库 运行sql文件 选择sql文件即…

微信小程序原生支持TS、LESS、SASS能力探究

文章目录 原生支持开始使用旧项目新建项目TS声明文件更新 功能说明less 使用全局变量sass 使用全局变量 可以参考原文 在之前开发小程序中&#xff0c;无法使用 less/sass 等 css 预编译语言&#xff0c;也无法使用 TS 进行开发&#xff0c;但在最新的编辑器版本中&#xff0c…

Running setup.py install for wxPython did not run successfully.

Running setup.py install for wxPython did not run successfully. 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开…

【Prompt Enhancer】如何优化prompt的内容

背景 在使用LLM的时候&#xff0c;提示词的好坏对模型的输出质量影响很大&#xff0c;提示词又是一个复杂工程&#xff0c;要写出优秀的提示词&#xff0c;需要丰富的经验。正因如此&#xff0c;各类Agent平台都会有自己的提示词增强功能&#xff0c;帮助用户编写提示词。 最…

java项目之基于Spring Boot智能无人仓库管理源码(springboot+vue)

项目简介 智能无人仓库管理实现了以下功能&#xff1a; 基于Spring Boot智能无人仓库管理的主要使用者分为&#xff1a; 管理员的功能有&#xff1a;员工信息的查询管理&#xff0c;可以删除员工信息、修改员工信息、新增员工信息 &#x1f495;&#x1f495;作者&#xff1a…

WebGL系列教程六(纹理映射与立方体贴图)

目录 1 前言2 思考题3 纹理映射介绍4 怎么映射&#xff1f;5 开始绘制5.1 声明顶点着色器和片元着色器5.2 修改顶点的颜色为纹理坐标5.3 指定顶点位置和纹理坐标的值5.4 获取图片成功后进行绘制5.5 效果5.6 完整代码 6 总结 1 前言 上一讲我们讲了如何使用索引绘制彩色立方体&a…