欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > 5.string类型

5.string类型

2024/10/23 15:49:33 来源:https://blog.csdn.net/xinhang10/article/details/143181962  浏览:    关键词:5.string类型

文章目录

  • 1.redis中的string - 字符串
  • 2.string命令讲解
    • 2.1set
      • 2.1.1flush+all = flushall 即冲洗(删除)所有key value 数据
    • 2.2get
    • 2.3mset
    • 2.4mget
    • 2.5setnx setex psetex
    • 2.6incr incrby decr decrby incrbyfloat
    • 2.7append
    • 2.8setrange
    • 2.9getrange
    • 2.10strlen
    • 2.11string命令小结
  • 3.string编码方式
  • 4.string应用场景
    • 4.1缓存功能
    • 4.2计数功能
    • 4.3共享会话(Session)
    • 4.4手机验证码
  • 5.string业务

大家好,我是晓星航。今天为大家带来的是 redis中string字符串 相关的讲解!😀

1.redis中的string - 字符串

Redis 中的字符串,直接就是按照二进制数据的方式存储的(不会做任何的编码转换,存的是啥,取出来就还是啥)

不仅仅可以存储文本数据 整数 普通的文本字符串 JSON xml 二进制数据(图片, 视频,音频…)

音频视频 体积可能会比较大

Redis 对于 string 类型,限制了大小最大是 512M

Redis 单线程模型,希望进行的操作都能比较快速

2.string命令讲解

2.1set

语法:

SET key value [expiration EX seconds | PX milliseconds] [NX|XX]

EX 设置 key 过期事件

set key value ex 10
相当于
set key value + expire key 10 两个语句的结合版(redis中使用一个命令操作两个过程可以节省资源,提高效率)

QQ_1724132463558

NX

如果 key 不存在,才设置。
如果 key 存在,则不设置(返回 nil)

QQ_1724132707366

XX

如果 key 存在,才设置。(相当于更新 key 的value)
如果 key 不存在,则不设置(返回nil)

QQ_1724132791674

key已存在,更新key中的value

QQ_1724132916730

key不存在,不设置,返回nil

QQ_1724132098109

如果 key 不存在, 创建新的键值对

如果 key 存在, 则是让新的 value 覆盖旧的 value.可能会改变原来的数据类型

原来这个 key 的 ttl(生存时间)也会失效

删库操作(类似mysql里的drop database):FLUSHALL - 可以把 redis 上所有的键值对都带走

QQ_1724132366800

2.1.1flush+all = flushall 即冲洗(删除)所有key value 数据

QQ_1724132509460

2.2get

语法:

GET key

返回值:key对应的value值

QQ_1724133183130

返回key2对应的值123

QQ_1724133151054

对于 GET 来说,只是支持,字符串类型的value。如果是 value 是其他类型,使用 GET 获取就会出错!

这里key3本质底层是使用quicklist(快速列表)的类型来排序的。

2.3mset

一次操作多组键值对。

语法:

mset key value [key value ...]

时间复杂度:O(N) N是key数量

返回值:永远是OK

QQ_1724133733131

2.4mget

一次操作多组键值对。

语法:

mget key [key ...]

时间复杂度:O(N) N是key数量

返回值:对应的 value 的列表

QQ_1724133733131

QQ_1724133385712 QQ_1724133410149

2.5setnx setex psetex

SETNX(检查原库中是否已经含有key,如果key不存在就设置。存在返回nil不设置。):

QQ_1724219050009

QQ_1724219090782

可以看到setnx和2.1中讲述的NX命令一样,只不过这里我们将set和nx写在一起了。

NX的含义见上图

SETEX(设置过期时间 单位是秒):

QQ_1724219227056

QQ_1724219245780

可以看到setex和2.1中讲述的EX命令一样,只不过这里我们将set和ex写在一起了。

EX的含义见上图。

QQ_1724219306132

并且这里在我们输入setex命令后,xshell客户端也提示了后面对应要写的信息分别为key键值对,时间,value值

PSETEX(设置过期时间 单位是毫秒):

QQ_1724219493380

这里的5000是5000毫秒即5s。查询返回的-2表示此时key3不存在。

QQ_1724219569088

并且这里在我们输入setex命令后,xshell客户端也提示了后面对应要写的信息分别为key键值对,时间,value值

针对 set 的一些常见用法,进行了缩写

之所以这样搞,就是为了让操作更符合人的直觉,(使用者的门槛就越低,要背的东西
就越少)

符合人的直觉 编程语言中, 很多的关键词, 都是和自然语言相关的

2.6incr incrby decr decrby incrbyfloat

QQ_1724219852690

incr:

针对整数value加1.

QQ_1724220224897

整数成功自增1.

QQ_1724220270657

只能针对于整数进行加1.(小数,字符都不能操作)

QQ_1724220555472

incr 操作的 key 如果不存在,就会把这个 key 的value 当作 0 来使用。

incrby:

针对整数value加n.

QQ_1724220352503

整数成功加9(此时n为9).

QQ_1724220438652

只能针对于整数进行加n.(小数,字符都不能操作)

QQ_1724220665566

incrby 操作的 key 如果不存在,就会把这个 key 的value 当作 0 来使用。

decr:

针对整数value减1.

QQ_1724220806648

整数成功自减1.

QQ_1724220864275

只能针对于整数进行减1.(小数,字符都不能操作)

QQ_1724220758870

decr 操作的 key 如果不存在,就会把这个 key 的value 当作 0 来使用。

decrby:

针对整数value减n.

QQ_1724221051637

整数成功自减n.

QQ_1724221112452

只能针对于整数进行减n.(小数,字符都不能操作)

QQ_1724220936755

decrby 操作的 key 如果不存在,就会把这个 key 的value 当作 0 来使用。

incrbyfloat:

把 key 对应的 value 进行 ±运算.运算的操作数可以是浮点数.

QQ_1724221191696

整数成功自加2.5(n此时为2.5).

QQ_1724221259285

可以看到我们使用incrbyfloat对key1进行加n操作时,无论是加整数还是加浮点数都是可以实现的。

QQ_1724221344496

但是对于字符还是不可以加。

QQ_1724221414594

incrbyfloat 操作的 key 如果不存在,就会把这个 key 的value 当作 0 来使用。

QQ_1724221529250

注意:我们redis操作中没有decrbyfloat命令,如果想减的话,只能通过使用命令incrbyfloat加上负数的形式来实现。

QQ_1724221624997

此时使用的就是incrbyfloat命令来加一个负数实现减法操作。

上述操作的时间复杂度,都是 O(1)

由于 redis 处理命令的时候,是单线程模型,多个客户端同时针对同一个 key 进行 incr 操作,不会引起"线程安全"问题

2.7append

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

语法:

append key value

时间复杂度:O(1)

返回值:拼接的字符串字节长度。

QQ_1724221943738

上图可以看到我们使用append命令将hello后拼接了world,使他变为了helloworld。

QQ_1724221991535

如果我们append的key不存在时,那么redis会默认key的value为空直接在上面拼接字符串。

QQ_1724222246640

如果我们拼接 “你好” 两个字,我们返回值为6个字节,并且我们用get得到的值为十六进制表示的汉字"你好"。

QQ_1724222193800

那么我们想看到key3以汉字 “你好” 的形式展现怎么办呢?

答:退出客户端,然后在启动客户端时后面加上 --raw 即可

QQ_1724222376180

退出客户端:ctrl + d

redis-cli --raw

QQ_1724222494199

此时我们key3中你好便是用中文字符的形式展现的了。

2.8setrange

语法:

setrange key offset value

这里的offset时偏移量(从第几个字节,开始替换)

QQ_1724258882776

这里我们就将key3的value值durant从第1个位置开始替换字符为四个o。

如果我们针对一个不存在的key在1个位置去设置一个偏移量并插入一小段字符串会出现什么效果呢?

QQ_1724259137833

凭空生成了一个字节,这个字节里的内容就是 0x00,banananice 就被追加到 0x00 的后面了

setrange 针对 不存在的 key 也是可以操作的.不过会把 offset 之前的内容填充成
0x00

2.9getrange

在c++和Java中叫法:

QQ_1724222850373

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

语法:

getrange key start end

时间复杂度:O(N)

返回值:string 类型的字串

redis的下标支持负数。

QQ_1724223407558

0代表第一个字符,-1代表最后一个字符。

如果此时使用getrange查询汉字会发生什么呢(一个汉字为3个字符)?

QQ_1724223519081

如果字符串中保存的是汉字,此时进行子串切分,很可能切出来的就不是完整
的汉字了,上述的代码,是强行切出了中间的四个字节,随便这么一切,切出的结果在 utf8 码表上不知道能査出啥了

QQ_1724223650863

QQ_1724223656994

2.10strlen

strlen获取字符串长度。单位是字节。

QQ_1724259392375

strlen key

时间复杂度:O(1)

返回值:string的长度。当key不存在时,返回0。单位是字节。

QQ_1724259543437

这里的key2内容为 “你好”,strlen返回值为6,因此redis中string使用的是utf8编码的。

一个汉字通常是 3 个字节(编码方式是 utf8)

Java 里头咋一个 2 字节的 char 就能表示汉字呢?

QQ_1724259644064

2.11string命令小结

image-20240822011422311

3.string编码方式

string有三个编码方式:

1.int 64 位/8字节 的整数

2.embstr 压缩字符串.适用于表示比较短的字符串。

3.raw 普通字符串.适用于表示更长的字符串.只是单纯的持有字节数组

image-20240822164604855

上述的编码方式在图片中可以很好的体现

image-20240822165227428

image-20240822165238127

小数则是使用字符串来存

意味着每次进行算术运算,都需要把字符串转成小数,进行运算,结果再转回字符串保存

4.string应用场景

4.1缓存功能

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

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

image-20240822165819188

整体的思路:

应用服务器访问数据的时候,先査询 Redis.如果 Redis 上数据存在了,就直接从 Redis 取数据交给应用服务器,不继续访问数据库了。

如果 Redis 上数据不存在,再读取 MySQL. 把读到的结果,返回给应用服务器。同时,把这个数据也写入到 Redis 中。

image-20240822170607358

刚才上述描述的过程相当于是把最近使用到的数据作为热点数据.(暗含了一层假设: 某个数据一旦被用到了,那么很可能在最近这段时间就被反复用到)

上述策略,存在一个明显的问题:
随着时间的推移,肯定是会有越来越多的 key 在 redis 上访问不到,从而从 mysql 读取并写入 redis 了,此时 redis 中的数据不是就越来越多嘛?

答:1.在把数据写给 redis 的同时,给这个 key 设置一个过期时间。

2.Redis 也在内存不足的时候,提供了 淘汰策略。

4.2计数功能

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

记录视频播放次数:

image-20240823163132977

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

4.3共享会话(Session)

image-20240823165646840

Session:在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。

Session和Cookie的主要区别:

image-20240823165826400

举个例子:

客户a 去酒店订房间想日后聚餐使用,于是找了 经理a 订房间。但是到了那天之后,经理a 放假了,此时是经理b上班,那么此时 客户a 找 经理b 要房间 经理b 就会去房间 订购本 上查一下是否 客户a 今天订了房间。那么这里的 订购本 就相当于 session

image-20240823173104070

上图为cookie方式,需要客户端自己本地存储。

image-20240823173135158

这里为session方式,我们将信息传给服务器存储一份,然后以cookie方式返回给客户端。

4.4手机验证码

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

image-20240823173016554

1.生成验证码

用户输入一下手机号 点击获取验证码

这里生成验证码我们需要加限制:

1分钟之内,最多获取 5 次验证码 或者 每次获取验证码必须间隔 30 秒

作用:主要是怕用户频繁获取验证码,导致服务器压力过大。

2.检查验证码

把短信收到的验证码这一串数,提交到系统中 系统进行验证验证码是否正确

5.string业务

业务:业务其实就是一个公司/一个产品,是如何解决一个/一系列问题的解决问题的过程,就可以称为是"业务

不同的公司,不同的产品,有不同的业务

不同的业务就需要不同的技术作为支撑

例如12306买火车票的业务:

众所周知我们中国有一个传统的节日-春节

在春节这天,中国各地会有大量的人口移动,因此带来的业务量是非常巨大以及复杂的,虽然在12306刚上线期间引入了非常多的技术用来提高访问速度和可用性。但是在放票的时候,整体的压力还是很大,还是很容易出问题。

之后为了缓解抢票压力过大,于是提出了一个新的方案:分时段放票。

image-20240823235915962

本来是一次放所有票
现在是分 5 次,每次放五分之一
这样就相当于把瞬间的压力降低到原来的 五分之一了
全国那么多车次,分 100 次放票 也很容易能做到

即相当于把流量分流了,使得服务器瞬间的压力缩小了。

间隔 30 秒

作用:主要是怕用户频繁获取验证码,导致服务器压力过大。

2.检查验证码

把短信收到的验证码这一串数,提交到系统中 系统进行验证验证码是否正确

感谢各位读者的阅读,本文章有任何错误都可以在评论区发表你们的意见,我会对文章进行改正的。如果本文章对你有帮助请动一动你们敏捷的小手点一点赞,你的每一次鼓励都是作者创作的动力哦!😘

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com