【Redis_Day5】String类型

【Redis_Day5】String类型

  • String
  • 操作String的命令
    • set和get:设置、获取键值对
    • mset和mget:批量设置、获取键值对
    • setnx/setex/psetex
    • incr和incrby:对字符串进行加操作
    • decr/decrby:对字符串进行减操作
    • incrbyfloat:浮点数加/减
    • 一个汉字究竟占几个字节?
    • append:字符串拼接
    • redis中字符串也有下标
    • getrange:返回key对应的string的子串
    • setrange:替换字符串指定部分
    • strlen:获取字符串的长度
    • 字符串相关命令小结
  • flushall:删库
  • String内部编码
  • String的应用场景
    • 缓存
    • 计数功能
    • 共享会话(Session)

String

redis中的所有key都是字符串类型,value也可能是字符串类型

String类型的值可以是字符串,包含⼀般格式的字符串或者类似JSON、XML格式的字符串;可以是数字,可以是整型或者浮点型;甚⾄可以是⼆进制流数据,例如图⽚、⾳频、视频等。但是⼀个字符串的最⼤值不能超过512MB。

redis内部存储字符串的时候,完全是按照⼆进制流的形式保存的,所以Redis是不会做任何编码转换的,客户端传⼊的命令中使用的是什么字符集编码,就存储什么字符集编码。
比如mysql8采用utf8mb4编码,mysql存数据的时候会默认对数据按照ytf8mb4进行编码。redis存数据时不会这样,redis内部没有设计字符集,所以使用redis时遇到乱码的概率很小。

操作String的命令

在redis中,操作不同类型的数据需要用不同的命令,下面总结一些操作String类型数据的命令:

set和get:设置、获取键值对

通过set和get可以操作字符串String。

set和get的基础操作不再赘述。

总结set的用法:

参考redis文档
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
其中:
[]相当于一个独立单元,表示可选项(可有可无)
|是或者意思
[]和[]之间可以同时存在

set后可以跟选项:

  1. set key1 value1 ex xxx (相当于set key1 value1和expire key xxx的结合,优化后减少了网络通信的次数且保证了命令原子性):把键值对存到redis中并为该键值对设置过期时间为xxx。如果key1不存在,创建新的键值对,如果key存在,让value1覆盖旧的value,覆盖过程中可能会改变原来的数据类型,此时原来key的ttl(生存时间)也会失效。
  2. 同理,set key1 value1 px xxx(相当于set key1 value1和pexpire key xxx的结合)
  3. set key1 value1 nx/xx:如果这条命令后加了nx或者xx,
    nx表示如果key1已经存在,返回nil本次设置无效,如果key1不存在,设置key1的值为value1并返回OK。
    xx表示如果key1不存在,返回nil本次设置无效,如果key1存在,用本次设置的value1覆盖之前设置的并返回OK。

nx是默认项。

总结get的用法:
get只支持字符串类型的value。如果value是其他类型,使用get获取就会出错。

比如用get获取list类型的value:
在这里插入图片描述

mset和mget:批量设置、获取键值对

相比于get和set,mset和mget可以一次操作多组键值对。优点很明显:减少网络通信的次数,提高效率。

学会使⽤批量操作,可以有效提⾼业务处理效率,但是要注意,每次批量操作所发送的键的数量也不是无节制的,否则可能造成单⼀命令执⾏时间过⻓,导致Redis阻塞。
在这里插入图片描述
总结mset的用法:
mset key value [key value ...]:一次性设置多个key的值。返回值永远是OK。
在这里插入图片描述

总结mget的用法:
mget key [key ...]:一次性获取多个key的值。如果对应的key不存在或者对应的数据类型不是string,返回nil。

在这里插入图片描述

mset和mget的时间复杂度都是O(N),N是当前命令中key的数量。所以时间复杂度也就是O(1)。

setnx/setex/psetex

setnx key value:setnx即加了nx选项的set命令。key存在,设置失败,key不存在,设置成功。

在这里插入图片描述

setex 键 值 过期时间:setex即加了ex选项的set命令。把键值对存到redis中并且设置过期时间,过期时间的单位是秒。

在这里插入图片描述
psetex 键 值 过期时间:psetex即加了px选项的set命令。过期时间的单位是ms。
在这里插入图片描述

incr和incrby:对字符串进行加操作

incr:针对value+1
incrby:针对value+n

总结incr的用法:

  1. incr key:key对应的value必须是整数(8byte整数)。返回值是value+1之后的值。如果key对应的value不是⼀个整型或者范围超过了64位有符号整型,则报错。

在这里插入图片描述
在这里插入图片描述

  1. incr key(key不存在):incr操作的key如果不存在,则视为key对应的value是0。
    在这里插入图片描述

总结incrby的用法:

  1. incrby key n:将key对应的string表⽰的数字加上n。
    如果key不存在,则视为key对应的value是0。如果key对应的string不是⼀个整型或者范围超过了64位有符号整型,则报错。
    在这里插入图片描述
  2. incrby可以加负数。相当于decrby。
    在这里插入图片描述

decr/decrby:对字符串进行减操作

decr:针对value-1
decrby:针对value-n

decr,decrby和incr,incrby的用法完全一样。

key5不存在:
在这里插入图片描述

incrbyfloat:浮点数加/减

decr、decrby、incr、incrby都只能算整数。
incrbyfloat:针对String类型的value进行加一个小数减一个小数操作。减一个小数相当于加上一个负的小数。vlalue可以是小数。

没有decrbyfloat这个命令!!!

如果key不存在,则视为key对应的value是0。如果key对应的不是string,或者不是⼀个浮点数,则报错。允许采⽤科学计数法表示浮点数。

在这里插入图片描述
decr、decrby、incr、incrby、incrbyfloat的时间复杂度都是O(1)。

一个汉字究竟占几个字节?

如果编码方式是utf8,一个汉字占3个字节。如果编码方式是unicode,一个汉字占2个字节。

最典型的就是在java中,char类型的单位是字符,一个汉字是一个字符,此时一个字符等于2个字节,因为char用的是Unicode;String类型的单位也是字符,一个汉字是一个字符,此时一个字符等于三个字节,因为String背后的编码方式utf8。在Java标准库中,char和String之间的变化方式非常丝滑,程序员感受不到。
mysql中的数据类型varchar(N),单位也是字符,一个汉字是一个字符,所以一个字符可能是多个字节。至于一个字符具体相当于多少个字节,要看varchar(N)采用的编码方式。

C++中字符串的单位是字节。

redis中字符串的单位是字节。但是redis内部没有设计任何字符集,一个汉字占3个字节是怎么回事?这是因为xshell终端默认的字符编码是utf8,在xshell终端输入汉字后,汉字先按照utf8编码的,而一个汉字在utf8字符集中通常是3个字节,所以在redis中一个汉字占三个字节。

每中编码方式的码表都不一样。同一个汉字,使用的编码方式不同,得到的对应值也不同。

append:字符串拼接

字符串也支持一些常用的操作,比如拼接,获取/修改字符串的内容,获取字符串的长度,redis中支持这样的命令。

总结append的用法:

  1. append key value:如果key已经存在并且是⼀个string,命令会将value追加到原有string的后边。如果key不存在,则效果等同于SET命令(创建一个新的键值对)。时间复杂度是O(1)。
    在这里插入图片描述在这里插入图片描述

  2. 返回值是追加完成之后String的长度。String长度的单位是字节。
    在这里插入图片描述get keys后,显示的是用utf8编码后的“你好”。(客户端传⼊的命令中使用的是什么字符集编码,就存储什么字符集编码。)
    在这里插入图片描述
    其中\x是转义字符,不属于数据内容。

  3. 在启动redis客户端时,加上--raw选项,可以使redis客户端自动把二进制数据尝试翻译。
    在这里插入图片描述

redis中字符串也有下标

redis中字符串也有下标,第一个字符处于0下标。最后一个字符可以用-1下标表示。

getrange:返回key对应的string的子串

总结getrange的用法:

  1. getrange key start end:返回key对应的string的子串,由start和end确定(左闭右闭)。start为0,表示的是字符串第一个字符。使⽤负数表示倒数。-1代表倒数第⼀个字符,-2代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据string的长度调整成正确的值。
    在这里插入图片描述
  2. 如果字符串中保存的是汉字,此时进行子串切分,很可能切出来的就不是完整的汉字了。在这里插入图片描述

setrange:替换字符串指定部分

总结setrange的用法:

  1. setrange key offset value :从下标offset开始,用value覆盖字符串。返回值是替换后的新的字符串的长度。0,表示的是字符串第一个字符。
    在这里插入图片描述在这里插入图片描述
  2. 如果当前key的value是一个中文字符串,进行setrange,容易出问题。就比如说一个汉字占三个字节,但是只覆盖了这个汉字的前两个字节。
  3. 如果key不存在,
    如下面例子:key1不存在:
    在这里插入图片描述
    \x是转义字符,表示这是一个十六进制数据。\x00表示凭空生成一个字节,这个字节里面的内容是0x00(0x00是16进制)。

strlen:获取字符串的长度

总结strlen的用法:

  1. strlen key:获取key对应的string的⻓度。当key存放的值不是string类型时,报错。返回值是字符串的长度。如果key不存在,返回0。
    在这里插入图片描述
    在这里插入图片描述

字符串相关命令小结

在这里插入图片描述

flushall:删库

flushall:清楚redis上的所有数据 ,也就是删库。
在这里插入图片描述

String内部编码

字符串类型的内部编码有3种:
• int:8个字节(64bit)的长整型。
• embstr:小于等于39个字节的字符串。(短字符串
• raw:大于39个字节的字符串。(长字符串)
Redis会根据当前值的类型和⻓度动态决定使用哪种内部编码实现。

redis存储小数,本质上是把小数当做字符串来存储。这意味这每次进行算术运算,都需要把字符串转换成小数,运算结束后再把结果转回字符串保存。
在这里插入图片描述

String的应用场景

缓存

redis作缓存的时候,常被用来存储“热点”数据。热点数据就是被高频使用的数据。不同场景下对高频的定义也不同。由于Redis具有⽀撑⾼并发的特性,所以缓存通常能起到加速读写和降低后端压⼒的作⽤。

redis+mysql组成的缓存存储架构:
在这里插入图片描述
假设把最近使用到的数据作为热点数据存储在redis中,解释上面的场景:
redis做缓存的时候,应用服务器访问数据,先查询Redis,如果redis上数据存在,就直接从redis上取数据交给应用服务器,不继续访问mysql了。如果redis上数据不存在,再读取mysql,把读到的结果返回给应用服务器的同时,把这个数据也写入到redis中。

但在上述场景中存在一个问题:随着时间的推移,有越来越多的key在redis上访问不到,从而从mysql读取并写入redis,redis中的数据会越来越多。
解决办法:

  1. 把数据写到redis中的同时,给这个key设置一个过期时间
  2. redis在内存不足的时候,提供了淘汰策略。

伪代码模拟上述场景,进一步理解String在其中的应用:
redis用key-value存储用户信息,
key:user:info:uid,value是String类型。
例如:
(JSON格式的数据)
key=user:info:student01,value=经过序列化后的01用户对象字符串;
key=user:info:student02,value=经过序列化后的02用户对象字符串;

mysql用表user_info保存用户信息:
在这里插入图片描述

//当用户发来请求时,假设业务根据用户uid获取用户信息:
//业务层
UserInfo getUserInfo(long uid) {
 //先查询redis,假设用户信息保存在"user:info:<uid>"对应的键中:
 String key = "user:info:" + uid;
 //从redis中获取对应的值
 String value = 这里执行redis中的get key命令;
//如果缓存命中(hit),即如果redis上存在这个信息
 if (value != null) {
    // 假设我们的⽤⼾信息是按照 JSON 格式存储的
    UserInfo userInfo = JSON反序列化(value);
    return userInfo;
  }
//如果redis上数据不存在,再读取mysql,把读到的结果返回给应用服务器的同时,把这个数据也写入到redis中(miss)
  if (value == null) {
 // 从mysql数据库中,根据 uid 获取⽤⼾信息
  UserInfo userInfo = MySQL执⾏SQL语句:select * from user_info where uid = <uid>
     // 如果mysql表中没有 uid 对应的⽤⼾信息
     if (userInfo == null) {
     响应 404
     return null;
     }
     // 如果mysql表中有 uid 对应的⽤⼾信息
     //1. 将⽤⼾信息序列化成 JSON 格式
     String value = JSON序列化(userInfo);
     //写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时(3600 秒)
     Redis 执⾏命令:set key value ex 3600
     //2. 返回⽤⼾信息
     return userInfo;
  } 
}

关于key的命名:
与MySQL等关系型数据库不同的是,Redis没有表、字段这种命名空间,而且也没有对键名有强制要求(除了不能使用⼀些特殊字符)。但设计合理的键名,有利于防止键冲突和项目的可维护性,比较推荐的⽅式是使用**"业务名:对象名:唯⼀标识:属性"**作为键名。
例如:
MySQL的数据库名为vs,用户表名为user_info,
那么对应的键名可以使用"vs:user_info:6379"、“vs:user_info:6379:name"来表示,如果当前Redis只会被⼀个业务使用,可以省略业务名"vs:”。
如果键名太长,则可以使用团队内部都认同的缩写替代,例如:
"user_info:6379:name"可以被"ui:6379:na"代替。毕竟键名过长,会导致Redis的性能明显下降的。

从redis中取出来的用户信息是String格式(JSON格式),通过JSON反序列化可以把它变成对象。
从mysql中取出来的用户信息是对象,通过JSON序列化可以把转成字符串然后再存到redis中。

计数功能

许多应⽤都会使⽤Redis作为计数的基础⼯具,它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源。
例如使用Redis来记录视频网站的视频播放次数:用户每播放⼀次视频,相应的视频播放数就会⾃增1。
在这里插入图片描述
redis并擅长数据统计,比如再上述场景中,统计播放量前100的视频有哪些,基于redis完成这个任务很麻烦。相比之下,如果是mysql存储上述数据,一个sql命令就完成了。但是用mysql记录,遇上高并发场景又容易挂。

解决办法:把redis上统计相关的数据通过异步的方式同步到统计数据仓库上,统计数据仓库可能是mysql,hdfs等。
异步方式不是redis收到xxx个播放请求就立即把它也写到仓库中,而是根据仓库的接收能力把数据持续地写入到仓库中,只要保证最终能把数据都正确写入到仓库中即可。

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

共享会话(Session)

会话是客户端和服务器再交互过程中产生的一些专属于该客户端的中间状态的数据。
cookie是浏览器的会话存储机制,session是服务器的会话存储机制。
cookie和session中都是用键值对存储数据的。

为了更好的理解共享会话(Session),先来看看**服务器之间不共享会话(session)**的情况:
session分散存储:
在这里插入图片描述
上面是一个分布式Web服务,在这个服务中,用户的Session信息(例如用户登录信息)保存在各自的服务器中,但这样会造成⼀个问题:出于负载均衡的考虑,分布式服务会将用户的访问请求均衡到不同的服务器上,并且通常无法保证用户每次请求都会被均衡到同⼀台服务器上,这样当用户刷新⼀次访问是可能会发现需要重新登录,这个问题是用户⽆法容忍的。
如何解决上述问题:

用redis集中管理session,即服务器之间通过redis共享会话session。
在这里插入图片描述
以上是Redis的字符串数据类型可以使⽤的三个典型场景,其适⽤场景远不止于此。


总结两个xshell热键:
ctrl+s:冻结当前画面。
ctrl+q:解除冻结。


下次见~
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux安装mysql57——笔记

rpm -qa | grep mysql有东西就rpm -e 文件名 下载 wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm安装 yum -y install mysql57-community-release-el7-10.noarch.rpm安装 yum -y install mysql-community-server如果出现Error: GPG c…

基于Java Springboot高校会议室预订管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

基于 NCD 与优化函数结合的非线性优化 PID 控制

基于 NCD 与优化函数结合的非线性优化 PID 控制 1. 引言 NCD&#xff08;Normalized Coprime Factorization Distance&#xff09;优化是一种用于非线性系统的先进控制方法。通过将 NCD 指标与优化算法结合&#xff0c;可以在动态调整控制参数的同时优化控制器性能。此方法特别…

数据库表设计范式

华子目录 MYSQL库表设计&#xff1a;范式第一范式&#xff08;1NF&#xff09;第二范式&#xff08;2NF&#xff09;第三范式&#xff08;3NF&#xff09;三范式小结巴斯-科德范式&#xff08;BCNF&#xff09;第四范式&#xff08;4NF&#xff09;第五范式&#xff08;5NF&…

中国省级新质生产力发展指数数据(任宇新版本)2010-2023年

一、测算方式&#xff1a;参考C刊《财经理论与实践》任宇新&#xff08;2024&#xff09;老师的研究&#xff0c;新质生产力以劳动者劳动资料劳动对象及其优化组合的质变为 基本内涵&#xff0c;借 鉴 王 珏 和 王 荣 基 的 做 法构建新质生产力发展水平评价指标体系如下所示&a…

【爬虫】Firecrawl对京东热卖网信息爬取(仅供学习)

项目地址 GitHub - mendableai/firecrawl: &#x1f525; Turn entire websites into LLM-ready markdown or structured data. Scrape, crawl and extract with a single API. Firecrawl更多是使用在LLM大模型知识库的构建&#xff0c;是大模型数据准备中的一环&#xff08;在…

Admin.NET框架前端由于keep-alive设置缓存导致的onUnmount未触发问题

bug版本&#xff1a;next分支&#xff0c;基于.NET6版本&#xff1b; 问题描述&#xff1a; 1、添加keep-alive后&#xff0c;在其下运行的组件会出现onActived(被关注时)和onDeactived(取消关注时)生命周期&#xff0c;而组件原有生命周期为onMounted(被创造时)和onUnmounted(…

机器学习day7-线性回归3、逻辑回归、聚类、SVC

7欠拟合与过拟合 1.欠拟合 模型在训练数据上表现不佳&#xff0c;在新的数据上也表现不佳&#xff0c;常发生在模型过于简单无法处理数据中的复杂模式时。 特征&#xff1a; 训练误差较高 测试误差也高 模型过于简化&#xff0c;不能充分学习训练数据中的模式 2.过拟合 …

【鸿蒙开发】第二十二章 IPC与RPC进程间通讯服务

目录 1 IPC与RPC通信概述 2 实现原理 3 约束与限制 4 使用场景 5 开发步骤 5.1 Native侧开发步骤 5.2 ArkTS侧开发步骤 6 远端状态订阅开发实例 6.1 使用场景 6.1.1 Native侧接口 6.2 ArkTS侧接口 6.3 Stub感知Proxy消亡&#xff08;匿名Stub的使用&#xff09; 1 …

【开发小技巧11】用经典报表实现badge list效果,根据回显内容用颜色加以区分

之前使用badge list实现首页指标数据回显&#xff0c;但是无法根据对应数据进行个性化动态展示&#xff0c;那要如何解决呢&#xff1f;下面就来看看如何通过经典报表实现badge list效果&#xff0c;根据回显内容用颜色加以区分。 普通经典报表 想要做成类似这样的效果并且能…

rust中解决DPI-1047: Cannot locate a 64-bit Oracle Client library问题

我们在使用rust-oracle crate连接oracle进行测试的过程中&#xff0c;会发现无法连接oracle&#xff0c;测试运行过程中抛出“DPI-1047: Cannot locate a 64-bit Oracle Client library”错误。该问题是由于rust-oracle需要用到oracle的动态连接库&#xff0c;我们通过安装orac…

cocos creator 3.8 一些简单的操作技巧,材质的创建 1

这是一个飞机的3D模型与贴图 导入到cocos中&#xff0c;法线模型文件中已经包含了mesh、material、prefab&#xff0c;也就是模型、材质与预制。界面上创建一个空节点Plane&#xff0c;将模型直接拖入到Plane下。新建材质如图下 Effect属性选择builtin-unlit&#xff0c;不需…

python oa服务器巡检报告脚本的重构和修改(适应数盾OTP)有空再去改

Two-Step Vertification required&#xff1a; Please enter the mobile app OTPverification code: 01.因为巡检的服务器要双因子认证登录&#xff0c;也就是登录堡垒机时还要输入验证码。这对我的巡检查服务器的工作带来了不便。它的机制是每一次登录&#xff0c;算一次会话…

数据集-目标检测系列- 荷花 莲花 检测数据集 lotus>> DataBall

数据集-目标检测系列- 荷花 莲花 检测数据集 lotus>> DataBall DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 贵在坚持&#xff01; 数据样例项目地址&#xff1a; * 相关项目 1&#xff09;数据集可视化项…

操作系统——揭开盖子

计算机执行时——取指执行 es:bx等于从0x9000开始&#xff0c;到0x90200结束

CTF 攻防世界 Web: SSRF Me write-up

题目名称-SSRF ME captcha 解码 目录扫描没有发现有用结果&#xff0c;根据提示 url 可能用来访问内部资源&#xff0c;根据题目名称可以猜测 ssrf。 其中 Captcha 用到 md5 加密截取&#xff0c;而且在每一次刷新网页时候会改变&#xff0c;可以写代码爆力枚举 Captcha 的值…

医学图像语义分割:前列腺肿瘤、颅脑肿瘤、腹部多脏器 MRI、肝脏 CT、3D肝脏、心室

医学图像语义分割&#xff1a;前列腺肿瘤、颅脑肿瘤、腹部多脏器 MRI、肝脏 CT、3D肝脏、心室 语义分割网络FCN&#xff1a;通过将全连接层替换为卷积层并使用反卷积上采样&#xff0c;实现了第一个端到端的像素级分割网络U-Net&#xff1a;采用对称的U形编解码器结构&#xff…

WPF窗体基本知识-笔记-命名空间

窗体程序关闭方式 命名空间:可以理解命名空间的作用为引用下面的控件对象 给控件命名:一般都用x:Name,也可以用Name但是有的控件不支持 布局控件(容器)的类型 布局控件继承于Panel的控件,其中下面的border不是布局控件,panel是抽象类 在重叠的情况下,Zindex值越大的就在上面 Z…

pytorch官方FasterRCNN代码详解

本博文转自捋一捋pytorch官方FasterRCNN代码 - 知乎 (zhihu.com)&#xff0c;增加了其中代码的更详细的解读&#xff0c;以帮助自己理解该代码。 代码理解的参考Faster-RCNN全面解读(手把手带你分析代码实现)---前向传播部分_手把手faster rcnn-CSDN博客 1. 代码结构 作为 to…

大数运算(加减乘除和输入、输出模块)

为什么会有大数呢&#xff1f;因为long long通常为64位范围约为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807&#xff0c;最多也就19位&#xff0c;那么超过19位的如何计算呢&#xff1f;这就引申出来大数了。 本博客适合思考过这道题&#xff0c;但是没做出来或…