Redis远程字典服务器(4)—— string类型详解

news2024/11/25 0:58:15

目录

一,string基本情况

二,string命令详解

2.1 set命令选项

2.2 setnx,setex

2.3 incr,incrby

2.4 decr,decrby

2.5 append拼接

2.6 getrange获取

2.7 setrange修改

2.8 strlen获取长度

2.9 总结

三,内部编码

四,string类型应用场景

4.1 缓存(cache)

4.2 计数(count)

4.3 会话(session)

一,string基本情况

  1. Redis中的字符串,直接就是按照二进制数据方式存储的,不会做任何的编码转换,存的是啥,取出来就是啥,这样就不仅仅能存文本数据了,整数,文本字符串,JSON,xml,甚至图片视频音频都可以存,但是很少存视频啥的,因为体积比较大
  2. 对于编码转换,我们在讲MySQL的时候,知道MySQL默认的字符集是拉丁文,插入中文就会失败,所以需要进行编码转换;但是Redis没有,所以Redis遇到乱码的概率更小
  3. 所以Redis对于string类型,限制了大小为512M,Redis单线程模型希望你进行的操作都能比较简单快速

二,string命令详解

2.1 set命令选项

前面说过,set命令后面还有一条很长的选项,现在就可以介绍下了:

  1. 方括号里面的EX,相当于在set创建键值对使设定过期时间,单位为秒,PX也是设置时间,单位是毫秒,中间的 “ | ” 表示 “ 或 ”,代表 EX 和 PX 只能同时存在一个:
  2. 后面方括号的NX和XX,其中NX表示如果key不存在就创建键值对,如果key存在就返回nil;XX是如果key存在就用新的value覆盖更新旧的value,如果key不存在就返回nil,一样的,“ | ”表示“ 或 ”,NX和XX只能用一个 
  3. “ FLUSHALL ”,这个命令是清除当前Redis上所有的键值对,俗称“删库”,在学习阶段我们可以使用该命令快速清除旧的键值对,但是以后在公司里后,绝对绝对绝对不能使用该命令!
  • get命令查询value时,只支持查字符串类型的value,如果value是其它类型,再使用get会返回错误
  • mset和mget的时间复杂度是O(N),N是你当前命令行给出的键值对的数量,所以可以认为是O(1) 

2.2 setnx,setex

这两个命令就是上面几个set包括选项的简写,那么为什么会有简写呢

  • 之所以这样搞,就是为了让操作“更符合人的直觉”,(使用的门槛更低,要记得东西更少)
  • 编程语言中,很多的关键词都是和自然语言相关的,后面我们去设置一些库,一些工具,写代码给别人用的时候,也尽量符合人们的直觉,不要设计得反直觉,俗称“反人类”

2.3 incr,incrby

这两个命令是对key的value做加法操作,其中incr是针对value + 1,incrby是针对value + n;所以这几个命令说是操作string,其实是在操作数字:

 

注意: 

  • 当value为其它类型或者为小数超过了64位,都会报错(64位相当于C++中的long long,Java中的long)
  • 当incr一个不存在的key时,会创建该key,并将value设置为1
  • incrby的n可以为负数,简单来说就是 “ +(-n) ” :

2.4 decr,decrby

decr 和 decrby 和上面的一样,只是变成了减法,其余规则和加法一样:

其实对于运算操作还有一个“ incrbyfloat ”,这个是针对浮点数的,而且这个没有decr版的,只能加上 负数 来实现减法,,然而以后我们很少使用浮点数去计数,所以这里了解一下就好啦~

上述的加法减法操作时间复杂度都是O(1),并且就算多个线程同时操作,也不会有线程安全问题 

2.5 append拼接

append是我们的老朋友了,C++用过很多,表示字符串拼接,在Redis这里的话,如果key存在,就把新value拼接到旧的value后面,如果key不存在,相当于set创建键值对(没法加选项)

然后是针对中文和编码的一些扩展: 

我们将value设置为中文,会返回6,而Redis的返回值是字节,而前面也说过Redis不会对字符做任何的处理,由于XShell的默认字符串编码是utf8,所以一个汉字的长度通常是3字节:

然后我们用get命令后,会显示如下结果:

可以看到我们的“你好”两个字变成了一串代码,这其实是因为Redis在存储时只按照二进制的方式存的,不会做任何的编码处理,所以get的时候读取到的也只有二进制数,然后将二进制数按照16进制转换就变成了我们看到的样子

其实我们可以把打印的这串结果复制一下,去百度随便找一个编码转换器,其实可以看到使用utf8编码转换后,依旧是“你好” 两个字:

再进一步,如果我们想让Redis直接给我把“你好”打出来,该咋操作呢?可以在启动Redis客户端时,带上 “ --raw ”,使Redis客户端能够将二进制数据尝试翻译:

  

2.6 getrange获取

这个命令表示 “ 获取字符串中指定范围的内容 ”,start和end就是要获取的字符串的起始位置和终止位置,具体可以参考C++的substr字符串分割函数,或者Java的substring函数:

  • Redis中指定的区间是闭区间,在编程的大圈中,区间大多都是“前闭后开”,但是也有像Redis这样的“前闭后闭”特殊情况
  • 正常下标都是从0开始的整数,但是Redis的下标是可以支持负数的,比如 -1 就是倒数第一个整数,下标为len - 1 的元素,这种允许下标为负数的机制和python一致
  • 但是如果字符串保存的是汉字,进行这种子串切分就不是完整的汉字了,C++中同样有该问题,但是Java不会,因为Java中字符串的基本单位是字符,C++中字符串的基本单位是字节
  • Java中的String 类会帮我们把汉字的编码转换都处理好,而C++对于汉字的处理就没那么完善,需要我们手动处理(推测原因可能是C++发展得比较早,对于中文没有较好的适配)

2.7 setrange修改

这个命令的作用就是“修改字符串具体位置的值”,命令选项中的“ offset ”也是我们的老朋友了,就叫做“ 偏移量 ”, 表示从第几个字节开始进行替换,后面的value就是要进行替换的新内容:

注意:

  •  修改后的value,会覆盖旧的,如果新的value比旧的长,会延长旧的
  • 如果当前value是中文字符串,再用setrange,会搞出问题的,会被解析成乱码
  • 当key不存在时,也会创建键值对,当offset为n时,会在最前面的位置凭空生成n字节,每个字节的内容是0x00,然后新value就会追加到后面(如果启动Redis时带了--raw选项,就不会显示 “ \x00 ”了):

2.8 strlen获取长度

这个很简单,就算获取value的长度,和上面部分命令的返回值的数一样,这里就不演示了哈,不过还是有几个地方需要注意:

  • 获取到的单位长度是字节,C++中字符串的长度就是以字节为单位,Java中字符串的长度以字符为单位,(Java中一个char == 2个字节,并且Java的char基于unicode这样的编码方式,就能表示中文等符号)
  • MySQL我们学过varchar(N),N的单位就是字符,MySQL中的字符,也是完整的汉字,这样的一个字符,可能是多个字节
  • utf8和Unicode是两种编码方式,Java中的char是unicode,是2字节,但是Java的String,用的是utf8,是3个字节,Java的标准库内部,在进行上述操作过程中,程序猿一般是感知不到编码方式的变换的
  • 所以C++一个汉字3个字节,Java是2字节

2.9 总结

命令执行效果

时间复杂度

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

三,内部编码

 字符串类型的内部编码主要有3种:

  • int:8个字节的长整型
  • embstr: <=39 字节的字符串(压缩字符串,适用于比较短的字符串)
  • raw:>39 字节的字符串 (普通字符串,适用于更长的字符串,只是单纯的持有字节数组)
  • Redis会根据当前值的类型和长度动态决定使用哪种内部编码实现

39这个数字,不是绝对的,一切还是要以具体业务为准,比如我们也可以将100个字节长度的value也用embstr来实现,但是有要求:

  1. 先看Redis是否提供了对应的配置项,可以修改39这个数字
  2. 如果没有提供配置项,我们就需要对Redis的源码进行魔改

很多大厂,都是自己造轮子,不用业界成熟的,因为开源的软件,往往考虑的是通用性,但是大厂往往会遇到一些刁钻的业务场景,所以需要针对很多的开源软件进行定制化

四,string类型应用场景

4.1 缓存(cache)

  • 整体的思路是,应用服务器访问数据库的时候,先查绚Redis,如果有,直接返回,如果没有就去MySQL去找,然后把该数据写进Redis再返回。Redis这样的缓存,经常用来存放热点数据(一个数据被用到了,那么有很高的概率会被重复用到,假设)
  • 问题:随着时间的推移,Redis里面的数据肯定是越来越多的 --> 所以我们可以设置过期时间,配合淘汰策略,清理过期的key,以后再详细介绍

4.2 计数(count)

计数功能最直白的例子就是:视频网站的视频播放次数 

  • 企业为啥老喜欢手机用户数据? --> 为了统计,进一步明确用户的需求 --> 根据需求进一步改进和迭代产品
  • Redis并不擅长数据统计,比如我要知道播放量前100的视频,Redis搞就很麻烦,但是用MySQL的话,一个sql语句就搞定了
  • Redis写入MySQL的步骤:异步,将播放量同步到其它数据源(异步的,不是来一个播放就立马写数据,因为那样做的话效率太低)

4.3 会话(session)

这个我们之前已经讲到过:Redis远程字典服务器(0)——分布式系统-CSDN博客

举个场景:

  1.  我去看病,医生给我做了检查开了一些药,然后让我“一周后”来复查
  2. 一周后我来了,但是医生换了一个,上一周的那个医生没上班,所以这个医生可能不了解我的情况
  3. 所以,这个医生就拿着我的医保卡一刷,在他的电脑上就出现了我之前的病例

针对上面的场景:

  1.  我是病人,相当于一个客户端,医生相当于服务器给我提供服务,由于病人可能会多次访问服务器,服务器就需要很好的了解病人的情况
  2. 而医生有多个,服务器也有多个,是会通过负载均衡来提供服务的,所以病人两次来看病可能是不同的医生
  3. 所以需要用一台服务器来单独存储病人的情况,叫做session服务器,在“分布式系统”博客已经讲过
  4. 这个记录病人的病例,诊断结果,治疗情况等,就是所谓的会话,是客户端和服务器在交互过程中产生的一些中间状态的数据;而且由于这些数据具有临时性,所以也可以用Redis来存

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

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

相关文章

迈威通信Wi-Fi无线交换机:让工业网络打破线缆束缚

随着《中国制造2025》等国家政策的推进&#xff0c;我国正在加速推动制造业向智能化和信息化转型升级。在这一背景下&#xff0c;工业互联网作为支撑智能制造的关键基础设施&#xff0c;其重要性愈发凸显。特别是在“万物互联”的今天&#xff0c;Wi-Fi不仅成为了日常生活的重要…

VIM 包,集成多种算法的数据缺失值处理工具!

生信碱移 VIM 缺失值处理 在组学分析中&#xff0c;尤其是在公开数据库的挖掘中&#xff0c;数据缺失是一个常见问题&#xff0c;这可能是由于样本处理、测量误差或技术限制等多种原因引起。例如&#xff0c;在转录组学研究中&#xff0c;某些基因的表达数据可能因实验失败而…

我主编的电子技术实验手册(15)——测量正弦信号

本专栏是笔者主编教材&#xff08;图0所示&#xff09;的电子版&#xff0c;依托简易的元器件和仪表安排了30多个实验&#xff0c;主要面向经费不太充足的中高职院校。每个实验都安排了必不可少的【预习知识】&#xff0c;精心设计的【实验步骤】&#xff0c;全面丰富的【思考习…

Qt (5)【Qt 的 qrc 机制高效管理项目静态资源】

阅读导航 引言一、qrc机制简介二、创建qrc机制并使用1. 创建⼀个qrc文件2. 添加已有资源3. 使用已加载资源 三、qrc机制的优缺点 引言 在上一篇文章中&#xff0c;我们深入探讨了QWidget作为Qt GUI框架中核心基类的重要性&#xff0c;以及它如何承载了构建丰富用户界面所需的各…

“传统”父母用手机 VS “时髦”父母玩手机

“传统”父母日常用智能手机&#xff0c;经常有些“拦路虎”&#xff0c;让他们在接触新事物的时候&#xff0c;如果搞不定就干脆不用了。现在也涌现出来很多“时髦”父母&#xff0c;能游刃有余的使用智能手机&#xff0c;如何让长辈在使用手机时更有松弛感&#xff0c;今天带…

Mapreduce_partition分区入门

分区 将输入的csv按照员工号拆分成每个员工&#xff0c;每个员工存储为员工对象&#xff0c;之后按每个员工的不同部门存储 pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:x…

力扣热题100_回溯_17_电话号码的字母组合

文章目录 题目链接解题思路解题代码 题目链接 17. 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示…

力扣面试经典算法150题:删除有序数组中的重复项 II

删除有序数组中的重复项 II 今天的题目是力扣面试经典150题中的数组的中等难度题: 删除有序数组中的重复项 II 题目链接&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/description/?envTypestudy-plan-v2&envIdtop-interview-150 …

Linux中yum、vim、gcc/g++的使用

目录 一、Linux 软件包管理器 yum 什么是软件包 关于 rzsz 查看软件包★ 如何安装软件★ 如何卸载软件★ Linux 开发工具 二、Linux编译器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 vim末行模式命令集 vim操作总结 如果在vim界面不小心按了Ctrl …

【Redis集群】集群原理最全解析

主从集群 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 数据同步概念 Replication Id和offset 在从节点发起数据同步的请求中&#xff0c;有两个重要的属性&#xff1a; Replication…

灵办AI探索之旅:颠覆传统的代码开发工具

前言 灵办AI是一个先进的人工智能工具&#xff0c;专注于提高软件开发和项目管理的效率。其核心功能包括代码生成、优化、评估和自动化修复&#xff0c;旨在帮助开发者和团队提升开发速度和代码质量。 体验地址&#xff1a;https://ilingban.com/browser_extension/?fromjj …

管道的学习

信号量&#xff1a;线程间有顺序的协调工作&#xff1b;&#xff08;用来描述可使用的资源个数&#xff09;&#xff1b; 信号量的个数反应的是资源的数量&#xff1b; 写线程 ---写资源 可以写数据的条件 1.开始时 &#xff0c;buf空的 2.读线程 读完了 读线程 buf充当读资源…

Particle Swarm Optimization粒子群算法

目录 1.粒子群算法入门 1.1 简单的优化问题 1.1.1 盲目搜索 1.1.2 粒子群算法流程图 1.1.3 粒子群算法的核心公式 1.1.4 预设参数 1.1.5 初始化粒子的位置和速度 1.1.6 计算适应度 1.1.7 循环体&#xff1a;更新粒子速度和位置 1.1.8 模型改进 2.深入研究粒子群算法 …

开办无人机培训机构,前期需要投入多少?

开办无人机培训机构的前期投入因多种因素而异&#xff0c;主要包括场地租赁、设备购置、师资薪酬、教学材料与课程开发、宣传推广、行政和运营费用&#xff0c;以及资质认证和审批费用等。以下是对这些费用的大致估算&#xff1a; 1. 场地租赁 费用范围&#xff1a;根据所在地…

“论NoSQL数据库技术及其应用”写作框架,软考高级,系统架构设计师

论文真题 随着互联网web2.0网站的兴起&#xff0c;传统关系数据库在应对web2.0 网站&#xff0c;特别是超大规模和高并发的web2.0纯动态SNS网站上已经显得力不从心&#xff0c;暴露了很多难以克服的问题&#xff0c;而非关系型的数据库则由于其本身的特点得到了非常迅速的发展…

CentOS系统下安装NVIDIA显卡驱动

一、安装显卡驱动 1.安装依赖项 yum -y install gcc pciutils yum -y install gcc yum -y install gcc-c yum -y install make2.查看内核版本 uname -a3.查看显卡版本 lspci | grep -i nvidia4.屏蔽系统自带的nouveau (1)查看nouveau lsmod | grep nouveau (2)打开blackl…

Java的反射原理

反射允许程序在运行时检查或修改其类、接口、字段和方法的行为。反射主要通过java.lang.reflect包中的类和接口实现&#xff0c;它主要用于以下目的&#xff1a; 在运行时分析类的能力&#xff1a;通过反射&#xff0c;可以在运行时检查类的结构&#xff0c;比如它的方法、构造…

MySQL(二)——CRUD

文章目录 CRUD新增全列插入指定列插入 查询全列查询指定列查询查询字段为表达式表达式不包含字段表达式包含一个字段表达式包含多个字段 补充&#xff1a;别名去重查询排序条件查询 补充&#xff1a;运算符区间查询模糊查询NULL的查询 分页查询 修改删除 CRUD CRUD是指创建&am…

【自动驾驶】ROS中的TF坐标变换(一):静态坐标变换

目录 引子ros中的右手坐标系补充&#xff1a;欧拉角及四元数理解旋转平移操作复合操作 运行坐标变换的例子坐标转换 静态坐标变换-发布坐标系信息创建功能包 静态坐标变换-订阅坐标系信息添加cpp订阅者主文件修改cmakelist文件编译报错的解决方案运行程序进行测试 引子 机器人…

设计模式---构建者模式(Builder Pattern)

构建者模式&#xff08;Builder Pattern&#xff09; 是一种创建型设计模式&#xff0c;旨在将复杂对象的构建过程与其表示分离。它允许使用相同的构建过程创建不同的表示。该模式通常用于构建复杂对象&#xff0c;这些对象由多个部分组成或具有多个可选属性。 构建者模式的核…