Redis数据结构之String字符串

news2024/9/21 22:40:37

二.String字符串

redis中的所有key都是字符串类型,只不过是value类型有差异。

redis中的字符串,直接就是按照二进制的方式存储的(不会做任何的编码转换(就好像mysql,它默认的字符集是拉丁文,插入中文就会失败,除非charset utf8),存的是啥,取出来的就是啥)。

这里的二进制存储,可不仅仅能存储文本数据也不仅仅能存储字符串,还可以存储整数,json,xml,图片/视频/音频……

但是音频视频提及可能比较大而redis对于string类型的存储有要求,限制大小是512MB,因为redis是单线程模型,希望进行的操作能很快

1.常见命令

set key value [ex seconds|px millseconds] [nx|xx]

中括号中的表示可写可不写

设置成功则返回ok,未执行则返回nil

ex:表示设置秒级过期时间

px:表示设置毫秒级过期时间

nx:表示只在key不存在时才设置,如果key已经存在,就不能设置(也就是不可修改key的值)

xx:表示只有key存在时才设置(也就是修改key的值),key不存在时不设置

如果nx和xx都没有写,那就表示key不存在时就将key添加到hash表中,key存在时就修改key的值

时间复杂度O(1)

get key 获取key对应的value

如果key不存在,就返回nil

注意,对于get只支持value为String类型的,如果该key对应的value是其他类型,使用get key就会报错

时间复杂度O(1)

mget key [key……] 一次性获取多个key的值

时间复杂度O(N),这里的N是key的数量,当key很少时,就近似看作O(1)。

mset 一次性设置多个key的值

但也不要太多,否则容易阻塞住

多次get和单次mget的区别:每一个命令都需要一次网络通信,所以使用mset/mget可以减少网络交互的次数,有效减少网络事件,性能相对较高

setnx 只有key不存在的情况下才可以设置;setxxkey存在时才可设置

设置成功返回1,未设置成功返回0

时间复杂度O(1)

2.计数命令

incr key 将key对应的String表示的数字增加一

如果key不存在,则视为key对应的value是0.如果key对应的value不是整形或者范围超过64为有符号整型,就会报错

时间复杂度O(1)

返回值是integer类型加完后的数值

incrby key decrement 将key对应的数加上指定的整数值

如果key不存在,默认key是0,如果key不是整形或超过64为有符号整型的范围,则报错

返回值,加完后的结果

时间复杂度O(1)

decr 将key对应的数减一

与incr同理

decrby 将key对应的值减去指定的整数值

incrbyfloat key increment 将key对应的值加上对应的数

这个命令与incrby的区别就是这里的key的值可以是浮点数,所加的值可以是整数也可以是浮点数

3.其他命令

append key value 在key对应的value后面追加指定的字符串

如果key不存在,其效果就相当于set。

返回值是追加完之后string字符串的长度

时间复杂度:如果追加到字符串不是特别特别长,那就可以看作是O(1)

如上可知,append返回值的长度单位是字节!!!而且通过get k 可以看出,redis的字符串,不会对字符编码做任何处理(redis不认识字符串,只认识字节)

当前,咱们使用的xshell终端,默认的字符编码方式是utf8,里面一个汉字是3个字节,所以在终端输入汉字后,就会utf8来编码并存储到redis中。get k时,得到的就是16进制的utf8编码。

那如果我们就是想要在get k时得到汉字呢?可以在启动redis客户端的时候加一个--raw选项,这就可以时redis客户端能够自动尝试把二进制数据进行翻译

如下:

getrange key start end

返回key对应的string字符串的子串,注意,这里的区间是闭区间,不像java中是左闭右开。可以使用复数表示倒数。-1表示倒数第一个字符,0表示第一个字符;超过string的偏移量时,会根据String的长度调整成正确的值

注意上面对于汉字的操作,这说明,这个偏移量也是按照字节数来分配的!!!

上述问题,在c++中同样存在,但java中没事。因为java中字符串的基本单位是字符,而c++中字符串的基本单位是字节

setrange key offset value覆盖字符串的一部分,从指定的偏移开始

返回值是替换后的字符串的长度

时间复杂度是O(N),N为value的长度,一般value较短,所以可以视为O(1)

同样的问题,这里的偏移量是按照字节计算的,所以如果这里的key的值是汉字的话,不正确的偏移会出问题。

还有一个问题,如果对不存在的key去进行setrange

由上可知,它会凭空多出几个字节

strlen key 获取key对应的string的长度

当key存放的类型不是string时就会报错

同样,单位是字节

时间复杂度O(1)

注意,java中的char时unicode编码,一个汉字是两个字节,然而String是utf8编码,一个汉字是三个字节。当调用string.charAt等类似的方法时,java标准库内部会惊醒字符编码方式的转换,而在进行上述操作的过程中,程序员感知不到编码方式的转换

flushall表示清除所有的key

4.内部编码

int:8个字节的长整型

embstr:小于等于39个字节的字符串。相当于压缩的表示形式

raw:大于39个字节的字符串

注意:

1.39这个数是不固定的,是可以修改的。

就比如某业务场景下:有很多key,类型都是String,但单个value的长度是100左右。如果更关注内存空间的占用,而不太在意效率等其他开销,就可以考虑使用embstr。

上述效果如何实现?1.先看看配置文件中有没有对应的配置项,2.如果没有就需要对源码进行魔改

2.整数直接使用int来存,准却来说是java中的long(因为是8个字节),但小数还是用字符串存储

所以在对小数进行加减运算时,就要先把字符串转化成小数,计算完后,再把结果转化成字符串。这样的转化是有开销的。所以redis计算整数时顺理成章的事情,而计算小数就要考虑成本开销。

5.String的典型应用场景

缓存功能

应用服务器访问数据:

先查询redis,若有则直接从redis获取数据并交给应用服务器;若无则去查询mysql,将读取到的数据交给应用服务器,同时把它也写到redis中。

为什么要同时写到redis中?redis只存热点数据(就是高频使用的数据),不同的应用场景下对高频的定义不同,其中一种定义就是近期使用过的数据。

但上述策略有一个问题:随着时间的推移,会有越来越多的key在redis上访问不到,从而要从mysql写到redis上,那么redis上的数据就会越来越多了。那这该怎么解决?目前有两种解决方案:一种是为这个key设置过期时间,另一种是redis有内存淘汰机制(后面会讲)

计数功能

许多应用都会使用redis作为计数的基础工具,它可以实现快速计数的功能,同时,数据可以异步处理或者落地到其他数据源。

比如记录视频的播放次数,每播放一次,对应的key就自增一次。由于redis自增很快,所以及时用户访问量很大,也可以应对的了。

而对于统计播放次数这样的操作,往往还需要进行其他转化、分析、处理,从而进一步对系统进行优化。所以就可以经redis导入其他存储介质,如hdfs中、mysql中(为了完成后续统计等相关需求。因为redis不擅长统计数据)

上面所说的导入到其他存储介质,也就是写入到其他数据源,使用的是异步的方式。什么是异步?就是说,不是来一个播放请求,就要立马写入一个数据同步到其他数据源,而是可以慢一点,慢一点没关系,只要保证最终都正确写入即可

共享会话

一个分布式的web服务,会将用户的session保存在各自的服务器上,但会出现这样的问题:处于负载均衡的考量,分布式服务会将用户的请求分不到不同的web服务器上,但是却无法保证每次请求都分发到同一个服务器上,这就会导致用户要多次登录。

为了解决这个问题,我们就可以将sessioon信息保存到一个公共服务器上,这个东西就可以使用redis来实现。这样的话,所有的会话数据就都可以被各个服务器共享了

手机验证码

步骤就是

1.生成验证码

2.获取验证码:

限制:一分钟内只能获取5次/每次获取的间隔必须超过30秒(主要是怕用户频繁获取验证码,对于我们服务器这边的压力过大)

3.检查验证码:把短信的数据提交到系统中,系统进行验证

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

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

相关文章

Linux 基础IO 2

读取与写入 read与fread 在基础IO 1中我们学会了open和fopen的函数这两个函数是用于为进程打开文件也可以理解为为进程和文件建立了一个链接使其可以交互。那我们建立号链接之后肯定还是需要对文件进行操作,现在我们先来了解读取操作。 read: 这是一…

Leetcode面试经典150题-94.二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2]示例 2: 输入:root [] 输出:[]示例 3: 输入:root [1] 输出&am…

SOMEIP_ETS_120: SD_Initial_Events_after_Subscribe_with_alternate_IPs

测试目的: 验证DUT在接收到Tester的SubscribeEventgroup消息后,能够向Tester指定的IP地址和端口发送SubscribeEventgroupAck确认消息以及对应的初始化字段。 描述 本测试用例旨在确保DUT能够正确处理SubscribeEventgroup消息,并按照消息中…

基于SpringBoot+Vue的健身房管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

自动化直播的未来:2024年必试的10款自动直播App曝光,教你轻松玩转直播!

自动化直播的未来:2024年必试的10款自动直播App曝光,教你轻松玩转直播! 随着人工智能技术的飞速发展,自动化直播已经成为当下最热门的趋势之一。2024年,众多创新的AI自动直播App如雨后春笋般涌现,它们不仅…

IO流中的异常捕获

Java简化 接口AutoCloseable

unity3d入门教程九

unity3d入门教程九 20.2播放音频20.3在代码中播放21.1延时调用21.2invoke API21.3消息调用22.1交互界面22.2添加canvas22.3canavas的位置22.4添加text 这里给一个资源网站,可以部分免费下载,音乐和音效超多,支持检索 爱给网 https://www.aige…

【Delphi】创建应用程序和 LiveBindings示例(FMX)

一、创建一个FMX程序 界面上放置上如下3个控件:TProgressBar1, TArcDial1,TTrackBar1。 二、打开LiveBindings Designer 设计器 三、在 LiveBindings Designer 中,您的绑定图只包含对象,您可以将它们连接起来。 四、在设计器中,在…

idea 恢复 pom 文件呈现灰色并带删除线

今天在 idea 中导入别人的项目时发现有几个 pom 文件是灰色的并带删除线。 可以用以下方式解决: 打开file - settings - build,execution,deployment - Build Tools - Maven - Ignored Files 把 pom.xml 前面的复选框去掉,去掉之后,点击 appl…

Kerberos自我总结Kerberos自我总结

1、协议原理与漏洞产生 1.1 kerberos Kerberos协议是一种基于票据Ticket的认证方式,它由三个角色组成,分别是客户端Client、服务端Server和秘钥分发中心KDC。 协议中的交互分为六步,为AS_REQ、AS_REP、TGS_REQ、TGS_REP、AP_REQ和AP_REP …

【Linux】进程地址空间和进程调度队列

🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:https://blog.csdn.net/qinjh_/category_12625432.html 目录 问题现象 进程地址空间 进一步理解 地址空间 Linux2.6内核进程调度队列 …

C++——string的了解和使用

目录 引言 为什么要学习string 1.C语言中的字符串 2.C中的字符串 auto和范围for 1.auto 1.1 auto的介绍 1.2 注意事项 2.范围for 标准库中的string类 1.string类的迭代器 1.1 begin()与end()函数 1.2 rbegin()与rend()函数 2.string类的初始化和销毁 3.string类…

【线程】线程的控制

本文重点:理解线程控制的接口 前言 内核中是没有很明确线程的概念的,只有轻量级进程的概念,不会提供直接给我们线程的系统调用,而会给我们提供轻量级进程的系统调用。我们用户是需要线程的接口的,在应用层&#xff0…

java重点学习-总结

十五 总结 https://kdocs.cn/l/crbMWc8xEZda (总结全部的精华) 1.面试准备 企业筛选简历规则简历编写注意事项(亮点)项目怎么找,学习到什么程度面试过程(表达结构、什么样的心态去找工作) 2.redis 缓存相关(缓存击穿、穿透、雪崩、缓存过期淘…

智能自行车码表:基于2605C语音芯片的创新开发方案

一、开发背景 随着科技的飞速发展和人们对健康生活的追求,自行车骑行已成为一种广受欢迎的绿色出行方式。智能自行车码表作为骑行者的得力助手,不仅记录骑行数据,还逐渐融入了更多智能化功能。然而,传统码表在语音提示、多语种支持…

Science Robotic 内在触觉实现直观的物理人机交互

触觉传感器和电子皮肤是为机器人提供物理交互感的常见设备,但当用于机器人的大面积覆盖时,它们会变得复杂且昂贵。德国宇航中心近期发表的Science Robotics研究工作,使用内部高分辨率关节力扭矩传感器,在机械臂中实现了固有的全身…

linux网络-----传输层

前言 一.传输层: 数据要交接应用层先通过传输层(给哪个程序发数据) 传输层作用:负责数据能够从发送端传输接收端。对于应用层来说有许多服务,传输层怎么知道把数据发给那个应用服务? 这时就有了端口号&am…

BMC 虚拟i2c访问PCA9545(switch芯片)后面的设备,为什么找不到PCA9545?

1.说明 1.1 背景 无意中看到PCA9545(switch芯片)后面有设备,但是PCA9545设备本身是连接到物理设备i2c上的,然而扫描该物理i2c bus,却找不到该设备。此篇文章主要找一下该原因的。 1.2 参考代码 当前使用的是ast2600芯片,可参考…

Mudslide

作者未提供代码

Qt/C++ TCP调试助手V1.1 新增图像传输与接收功能(附发布版下载链接)

发布版本链接 通过百度网盘分享的文件:TCP调试助手V1.zip(含客户端与服务器) 链接:https://pan.baidu.com/s/14LTRPChPhYdwp_s6KeyBiA?pwdcedu 提取码:cedu 基于Qt/C实现了一款功能丰富的TCP服务器与客户端调试助手…