[Redis] Redis中的String类型

news2024/9/20 0:10:09

🌸个人主页: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.coloradmin.cn/o/2120467.html

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

相关文章

comfyui中的几种inpainting工作流对比

inpainting方法集合_sdxl inpaint教程-CSDN博客文章浏览阅读150次。1.32G,通过它可以将所有的sdxl模型转成sdxl_inpaint模型,源于fooocus_inpaint_head,将9个通道压缩为4个通道的小型卷积网络,标准模型unet有4个通道,重绘模型有9个通道,inpaint_model_head和inpaint mode…

Jupyter Notebook 修改默认路径

Jupyter Notebook 修改默认路径 1、默认路径 安装anaconda后,jupyter notebook默认路径下很多文件,很乱,所以为了创建一个干净的文件夹专门存放我的python项目,修改jupyter notebook的文件路径 这是我现在打开jupyter notebook…

常见概念 -- 光回波损耗

什么是回波损耗 回波损耗,又称为反射损耗,当高速信号进入或退出光纤的某个部分(例如光纤连接器),不连续和阻抗不匹配会引起反射,这就是光纤回波损耗。器件的回波损耗Return Loss(RL)是光信号的输入端口的反…

【信创】推荐一款在龙芯CPU终端上使用的WiFi接收器 _ 统信 _ 麒麟

原文链接:【信创】推荐一款在龙芯CPU终端上使用的WiFi接收器 | 统信 | 麒麟 Hello,大家好啊!今天给大家带来一篇关于在龙芯CPU架构的台式机上如何安装和使用无线WiFi接收器的文章。对于使用龙芯CPU的台式机用户来说,安装并配置WiF…

新版智慧职教(zjy2域名开头的)怎么下载课件?一篇文章教会你

文章目录 1、引言2、痛点3、解决方法 🍃作者介绍:双非本科大四网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发,目前开始人工智能领域相关知识的学习 🦅个人主页&#xff…

Redis面试必备:Redis两种内存回收策略,Redis键空间、过期字典等

请记住胡广一句话,所有的中间件所有的框架都是建立在基础之上,数据结构,计算机网络,计算机原理大伙一定得看透!!~ 1. Redis数据库 1.1 Redis数据库的理解 我们可以把Redis的数据库和MySQL的数据库理解成…

运维学习————Zabbix监控框架(1)

目录 一、监控 1、概念 2、作用 3、创建监控框架 老牌监控框架 新款王牌监控框架 二、zabbix简介 1、概述 2、核心功能 三、主要组件及运行原理 1、主要组件 Zabbix Server Zabbix Agent Zabbix Proxy Zabbix Web 界面 数据库 其他 2、监控架构原理图 原…

通义千问Qwen2-7b-instruct部署

前言 https://www.modelscope.cn/models/qwen/Qwen2-7B-Instruct 其实完全可以按照这个介绍来装,不过容易遇到一些问题,新学习,也是记录一下 环境 python 3.10 在自己电脑上用conda创建一个新环境找租用的服务器租一台,3090一…

超微小间距COB大尺寸LED智能会议一体机玩转高清视频会议显示市场

在当今这个数字化飞速发展的时代,高清视频会议已成为企业沟通协作不可或缺的一部分。随着技术的不断革新,超微小间距COB大尺寸LED智能会议一体机以其卓越的性能和多元化的功能,正逐步引领并重塑高清视频会议显示市场的格局。这款集大成者的诞…

Android SystemUI组件(05)状态栏-系统状态图标显示管理

该系列文章总纲链接:专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明: 说明:本章节持续迭代之前章节的思维导图,主要关注下方 SystemBars分析中状态栏中的部分-系统状态图标显示&管理 即可。 1 系统状态图标显…

基于Python的机器学习系列(32):PyTorch - 循环神经网络(RNN)

在本篇文章中,我们将探索循环神经网络(RNN),这是一种特别适用于时间序列数据或文本数据的神经网络模型。在RNN中,当前的输出不仅取决于当前的输入,还受到前一步输出的影响,从而能够捕捉序列数据…

Java 入门指南:JVM(Java虚拟机)—— Java 类文件结构

文章目录 字节码JVM 与字节码字节码的生成过程 Class 文件结构魔数(Magic Number)Class 文件版本号(Minor&Major Version)常量池(Constant Pool)访问标志(Access Flags)前类(This Class&…

Pygame中Sprite类实现多帧动画3-3

4 使用自定义类MySprite 使用自定义类MySprite实现多帧动画的步骤是首先创建MySprite类的实例,之后使用相关函数对该实例进行操作。 4.1 创建MySprite类的实例 创建MySprite类的实例的代码如图12所示。 图12 创建MySprite类的实例的代码 其中,变量dr…

2024年CCPC网络赛A题题解 —— 军训Ⅰ(gym105336A)

个人认为很唐的一道题,考虑到不少人可能懒得写,我这里给大家发个代码叭,还有一点点题解(因为真的不是很难)。这是题面: 然后我来讲讲怎么做,不觉得会有多少人题目意思都理解不了叭?这…

Javaweb项目-调用接口-如何在服务器端跳转网页后显示并弹出对话框代码

Webapp 项目中在java包下新建一个服务端类 使用JOptionPane框架组件 调用showMessageDialog的方法实现 四个参数null,"这是一个信息对话框","信息",JOptionPane.INFORMATION_MESSAGE 还有确认对话框的代码showConfirmDialog package servlet;import java…

k9s 是什么?有什么功能?

目录 k9s 是什么? 有什么功能? 手动安装 K9s(Windwos) 将 k9s.exe 添加到系统 PATH 启动 K9s k9s 是什么? K9s 是一个命令行工具,用于通过一个图形化的终端界面(类似于图形化用户界面但在命…

【Linux】常用的命令

文章目录 lsls -l / touchcdpwdcatechovim打开文件编辑内容保存退出 mkdirrmmvcpmangreppsnetstat总结 : ls ls > list 列出当前目录下都有哪些内容(文件/目录) 直接输入 ls,是查看当前目录的情况;输入 ls/ 就是看…

检查你的防病毒软件是否可以阻止这 5 个测试恶意软件文件

从网络安全专家到你,每个人都知道你应该使用防病毒软件来保护你的电脑免受黑客、病毒和其他类型的网络威胁。 但即使你这些年来一直在努力使用防病毒程序,你怎么知道它真的有效呢? 安全专家已经想到了这一点,并创建了几种类型的…

TMS320F28335芯片及使用介绍

1、简介 CPU性能的好坏不仅取决于主频大小,还需要看其整体架构集成性能、运算能力与指令体系。TMS320C2000系列DSP集微控制器和高性能 DSP 的特点于一身,具有强大的控制和信号处理能力,能够实现复杂的控制算法。TMS320C2000 系列DSP 片上整合了Flash存储器、快速的AD转换器…

基于微信小程序+Java+SSM+Vue+MySQL的付费自习室预订管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSSMVueMySQL的付费自习室预订管理系统【…