redis—String字符串

news2024/9/23 22:47:00

目录

前言

1.字符串数据类型

2.常见命令

3.典型应用场景


前言

字符串类型是Redis最基础的数据类型,关于字符串需要特别注意: 1)首先Redis中所有的键的类型都是字符串类型,而且其他几种数据结构也都是在字符串类似基础.上构建的,例如列表和集合的
元素类型是字符串类型,所以字符串类型能为其他4种数据结构的学习奠定基础。2) 其次,如图2-7所示,字符串类型的值实际可以是字符串,包含-般格式的字符串或者类似JSON、XML 格式的字符串;数字,可以是整型或者浮点型;甚至是二进制流数据,例如图片、音频、视频等。不过一个字符串的最大值不能超过512 MB。

由于Redis内部存储字符串完全是按照二进制流的形式保存的,所以Redis是不处理字符集
编码问题的,客户端传入的命令中使用的是什么字符集编码,就存储什么字符集编码。

1.字符串数据类型

2.常见命令

SET
将string类型的value设置到key中。如果key之前存在,则覆盖,无论原来的数据类型是什么。之
前关于此key的TTL也全部失效。
语法:

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

命令有效版本: 1.0.0之后
时间复杂度: 0(1)
选项:
SET命令支持多种选项来影响它的行为:
EX seconds一使用秒作为 单位设置key的过期时间。
PX milliseconds 一使用毫秒作为 单位设置key的过期时间。
NX —只在key不存在时才进行设置,即如果key之前已经存在,设置不执行。
XX一只在key存在时才进行设置,即如果key之前不存在,设置不执行。
注意:由于带选项的SET命令可以被SETNX、SETEX、 PSETEX 等命令代替,所以之后的版本
中,Redis 可能进行合并。
返回值:
●如果设置成功,返回OK。.
●如果由于SET指定了NX或者XX但条件不满足,SET不会执行,并返回(nil)。
示例:

redis> EXISTS mykey
(integer) 0
redis> SET mykey "Hello"
OK
redis> GET mykey
"Hello"
redis> SET mykey "World" NX
(nil)
redis> DEL mykey
(integer) 1
redis> EXISTS mykey
(integer) 0
redis> SET mykey "World" XX
(nil)
redis> GET mykey
(nil)
redis> SET mykey "World" NX
OK
redis> GET mykey
"World"
redis> SET mykey "Will expire in 10s" EX 10
OK
redis> GET mykey
"Will expire in 10s"
redis> GET mykey # 10秒之后
(nil)

GET
获取key对应的value。如果key不存在,返回nilo如果value的数据类型不是string,会报错。
语法:

GET KEY

命令有效版本: 1.0.0之后
时间复杂度: O(1)
返回值: key 对应的value,或者nil当key不存在。
示例:

redis> GET nonexisting
(nil)
redis> SET mykey "Hello"
"OK"
redis> GET mykey
"Hello"
redis> DEL mykey
(integer) 1
redis> EXISTS mykey
(integer) 0
redis> HSET mykey name Bob
(integer) 1
redis> GET mykey
(error) WRONGTYPE Operation against a key holding the wrong kind of value

MGET
一次性获取多个 key的值。如果对应的key不存在或者对应的数据类型不是string,返回nilo
语法:

MGET key [key ...] 

命令有效版本: 1.0.0之后
时间复杂度: O(N) N是key数量
返回值:对应value的列表
示例:

redis> SET key1 "Hello"
"OK"
redis> SET key2 "World"
"OK"
redis> MGET key1 key2 nonexisting
1) "Hello"
2) "World"
3) (nil)

MSET
一次性设置多个key的值。
语法:

MSET key value [key value ...] 

命令有效版本: 1.0.1 之后
时间复杂度: O(N) N是key数量
返回值:永远是OK
示例:

redis> MSET key1 "Hello" key2 "World"
"OK"
redis> GET key1
"Hello"
redis> GET key2
"World"

图2-8多次get vs单次mget:

如图2-8所示,使用mget / mset由于可以有效地减少了网络时间,所以性能相较更高。假设网络耗
时1毫秒,命令执行时间耗时0.1毫秒,则执行时间如表2-2所示。

表2-21000次get和1次mget对比:

学会使用批量操作,可以有效提高业务处理效率,但是要注意,每次批量操作所发送的键的数量也不是无节制的,否则可能造成单一命令执行时间过长,导致Redis阻塞。

SETNX
设置key-value但只允许在key之前不存在的情况下。
语法:

SETNX key value 

命令有效版本: 1.0.0之后
时间复杂度: 0(1)
返回值: 1表示设置成功。0表示没有设置。
示例:

redis> SETNX mykey "Hello"
(integer) 1
redis> SETNX mykey "World"
(integer) 0
redis> GET mykey
"Hello"

SET、SET NX和SET XX的执行流程如图2-9所示。
图2-9SET、SET NX、SET XX执行流程

INCR
将key对应的string表示的数字加- -。如果key不存在,则视为key对应的value是0。如果key对
应的string不是一个整型或者范围超过了64位有符号整型,则报错。
语法:

INCR key

命令有效版本: 1.0.0之后
时间复杂度: O(1)
返回值: integer 类型的加完后的数值。.
示例:

redis> EXISTS mykey
(integer) 0
redis> INCR mykey
(integer) 1
redis> SET mykey "10"
"OK"
redis> INCR mykey
(integer) 11
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> INCR mykey
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> INCR mykey
(error) value is not an integer or out of range

INCRBY
将key对应的string表示的数字加上对应的值。如果key不存在,则视为key对应的value是0。如
果key对应的string不是一个整型或者范围超过了64 位有符号整型,则报错。
语法:

INCRBY key decrement 

命令有效版本: 1.0.0 之后
时间复杂度: O(1)
返回值: integer 类型的加完后的数值。
示例:

redis> EXISTS mykey
(integer) 0
redis> INCRBY mykey 3
(integer) 3
redis> SET mykey "10"
"OK"
redis> INCRBY mykey 3
(integer) 13
redis> INCRBY mykey "not a number"
(error) ERR value is not an integer or out of range
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> INCRBY mykey 3
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> INCRBY mykey 3
(error) value is not an integer or out of range

DECR
将key对应的string表示的数字减- -。如果key不存在,则视为key对应的value是0。如果key对
应的string不是一个整型或者范围超过了64位有符号整型,则报错。
语法:

DECR key 

命令有效版本: 1.0.0之后
时间复杂度: O(1)
返回值: integer 类型的减完后的数值。
示例:

redis> EXISTS mykey
(integer) 0
redis> DECR mykey
(integer) -1
redis> SET mykey "10"
"OK"
redis> DECR mykey
(integer) 9
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> DECR mykey
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> DECR mykey
(error) value is not an integer or out of range

DECYBY
将key对应的string表示的数字减去对应的值。如果key不存在,则视为key对应的value是0。如
果key对应的string不是一个整型或者范围超过了64位有符号整型,则报错。
语法:

DECRBY key decrement

命令有效版本: 1.0.0之后
时间复杂度: O(1)
返回值: integer 类型的减完后的数值。
示例:

redis> EXISTS mykey
(integer) 0
redis> DECRBY mykey 3
(integer) -3
redis> SET mykey "10"
"OK"
redis> DECRBY mykey 3
(integer) 7
redis> DECRBY mykey "not a number"
(error) ERR value is not an integer or out of range
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> DECRBY mykey 3
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> DECRBY mykey 3
(error) value is not an integer or out of range

INCRBYFLOAT
将key对应的string表示的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果
key不存在,则视为key对应的value是0。如果key对应的不是string,或者不是一个浮点数,则报
错。允许采用科学计数法表示浮点数。
语法:

INCRBYFLOAT key increment 

命令有效版本: 2.6.0之后
时间复杂度: O(1)
返回值:加/减完后的数值。
示例:

redis> SET mykey 10.50
"OK"
redis> INCRBYFLOAT mykey 0.1
"10.6"
redis> INCRBYFLOAT mykey -5
"5.6"
redis> SET mykey 5.0e3
"OK"
redis> INCRBYFLOAT mykey 2.0e2
"5200"

很多存储系统和编程语言内部使用CAS机制实现计数功能,会有一定的CPU开销,但在Redis中完全不存在这个问题,因为Redis是单线程架构,任何命令到了Redis服务端都要顺序执行。

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

APPEND KEY VALUE 

命令有效版本: 2.0.0 之后
时间复杂度: O(1).追加的字符串-般长度较短, 可以视为O(1). 
返回值:追加完成之后string的长度。
示例:

redis> EXISTS mykey
(integer) 0
redis> APPEND mykey "Hello"
(integer) 5
redis> GET mykey
"Hello"
redis> APPEND mykey " World"
(integer) 11
redis> GET mykey
"Hello World"

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

GETRANGE key start end 

命令有效版本: 2.4.0之后
时间复杂度: O(N). N为[start, end]区间的长度.由于string通常比较短,可以视为是O(1)
返回值: string 类型的子串
示例:

redis> SET mykey "This is a string"
"OK"
redis> GETRANGE mykey 0 3
"This"
redis> GETRANGE mykey -3 -1
"ing"
redis> GETRANGE mykey 0 -1
"This is a string"
redis> GETRANGE mykey 10 100
"string"

SETRANGE
覆盖字符串的一部分,从指定的偏移开始。
语法:

SETRANGE key offset value

命令有效版本: 2.2.0之后
时间复杂度: O(N), N为value的长度.由于一般给的value比较短,通常视为0(1).
返回值:替换后的string的长度。
示例: 

redis> SET key1 "Hello World"
"OK"
redis> SETRANGE key1 6 "Redis"
(integer) 11
redis> GET key1
"Hello Redis"

STRLEN 
获取key对应的string的长度。当key存放的类似不是string时,报错。
语法:

STRLEN key 

命令有效版本: 2.2.0之后
时间复杂度: O(1)
返回值: string 的长度。或者当key不存在时,返回0。
示例:

redis> SET mykey "Hello world" 1
"OK"
redis> STRLEN mykey
(integer) 11
redis> STRLEN nonexisting
(integer) 0

命令小结
表2-3是字符串类型命令的效果、时间复杂度,开发人员可以参考此表,结合自身业务需求和数
据大小选择合适的命令。

字符串类型命令小结:

内部编码
字符串类型的内部编码有3种:
●int: 8个字节的长整型。
●embstr:小于等于39个字节的字符串。
●raw:大于39个字节的字符串。
Redis会根据当前值的类型和长度动态决定使用哪种内部编码实现。
整型类型示例如下:

127.0.0.1:6379> set key 6379
OK
127.0.0.1:6379> object encoding key
"int"

短字符串示例如下:

# ⼩于等于 39 个字节的字符串
127.0.0.1:6379> set key "hello"
OK
127.0.0.1:6379> object encoding key
"embstr"

长字符串示例如下:

# ⼤于 39 个字节的字符串
127.0.0.1:6379> set key "one string greater than 39 bytes ........"
OK
127.0.0.1:6379> object encoding key
"raw"

3.典型应用场景

缓存功能:

redis作为缓冲层,MySQL作为存储层,绝大部分的请求数据都是从redis中获取,由于redis支持高并发的特性,所以缓存能够起到加速读写降低后端压力的作用。

redis和MySQL组成的缓存存储结构

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

共享会话(Session)
如图2-12所示,一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自的服务器中,但这样会造成一个问题:出于负载均衡的考虑,分布式服务会将用户的访问请求均衡到不同的服务器上,并且通常无法保证用户每次请求都会被均衡到同一台服务器上,这样当用户刷新一
次访问是可能会发现需要重新登录,这个问题是用户无法容忍的。
图2-12 Session分散存储

为了解决这个问题,可以使用Redis将用户的Session信息进行集中管理,如图2-13所示,在这种模
式下,只要保证Redis是高可用和可扩展性的,无论用户被均衡到哪台Web服务器上,都集中Redis中查询、更新Session信息。
图2-13 Redis集中管理Session

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

此功能可以使用以下伪代码说明基本实现思路:

String 发送验证码(phoneNumber) {
    key = "shortMsg:limit:" + phoneNumber;
    // 设置过期时间为 1 分钟(60 秒)
    // 使⽤ NX,只在不存在 key 时才能设置成功
    bool r = Redis 执⾏命令:set key 1 ex 60 nx
    if (r == false) {
        // 说明之前设置过该⼿机的验证码了
        long c = Redis 执⾏命令:incr key
        if (c > 5) {
            // 说明超过了⼀分钟 5 次的限制了
            // 限制发送
            return null;
        }
    }
    // 说明要么之前没有设置过⼿机的验证码;要么次数没有超过 5 次
    String validationCode = ⽣成随机的 6 位数的验证码();
    validationKey = "validation:" + phoneNumber;
    // 验证码 5 分钟(300 秒)内有效
    Redis 执⾏命令:set validationKey validationCode ex 300;
    // 返回验证码,随后通过⼿机短信发送给⽤⼾
    return validationCode ;
}
// 验证用户输⼊的验证码是否正确
bool 验证验证码(phoneNumber, validationCode) {
    validationKey = "validation:" + phoneNumber;
    String value = Redis 执⾏命令:get validationKey;
    if (value == null) {
        // 说明没有这个⼿机的验证码记录,验证失败
        return false;
    }
    if (value == validationCode) {
        return true;
    } else {
        return false;
    }
}

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

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

相关文章

ROS xacro优化URDF

Xacro是ROS中的一个工具,用于简化URDF文件的编写。它的主要目的是构造更短、更易读的XML文件,同时保持与URDF的兼容性。 以下是Xacro的基本语法和用法: 1、属性设置和算数运算: 可以使用xacro:property来定义常量或变量&#xf…

《Git快速入门》Git分支

1.master、origin、origin/master 区别 首先搞懂git分支的一些名称区别: master : Git 的默认分支名字。它并不是一个特殊分支、跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它&#xff0c…

利用markdown语法,写出数学公式以及常用符号【持续更新!!!】

1.希腊字母 数学表达式Markdown语法α\alphaβ\betaγ\gammaδ\deltaε\epsilonζ\zetaη\etaθ\thetaι\iotaκ\kappaλ\lambdaμ\muν\nuξ\xiο\omicronπ\piρ\rhoσ\sigmaτ\tauυ\upsilonφ\phiχ\chiψ\psiω\omega 2.基本表达式 数学表达式Markdow语法xx^2y₁y_1∞\…

医学影像处理与智能医学:数据集资源和云端加速路径

医学影像处理识别是一种利用计算机技术影像进行识别、分析和处理的方法。它主要应用于医学影像学领域,如 X 射线、CT 扫描、MRI 和超声等。通过图像处理技术,可以对这些影像进行数字化处理,提取有用信息,辅助医生进行疾病诊断、治…

如何编写高效清晰的嵌入式C程序

作为嵌入式工程师,怎么写出效率高、思路清晰的C语言程序呢? 要用C语言的思维方式来进行程序的构架构建 要有良好的C语言算法基础,以此来实现程序的逻辑构架 灵活运用C语言的指针操作 虽然看起来以上的说法很抽象,给人如坠雾里的感觉&…

【Element】el-select下拉框实现选中图标并回显图标

一、背景 需求&#xff1a;在下拉框中选择图标&#xff0c;并同时显示图标和文字&#xff0c;以便用户可以直观地选择所需的图标。 二、功能实现 <template><div><el-table ref"table" :data"featureCustom2List" height"200"…

AXI总线协议---关键信号波形图分析

写过程协议图 读过程协议图 读协议执行顺序图 写协议顺序图 单箭头表示两个信号谁先有效无所谓&#xff0c;双箭头表示必须要等到前一个信号有效才能将后面的信号有效 如何体现协议图中的通道理解 声明&#xff1a;以上图均采用AMBA总线文档图 写过程关键信号 主机 写地址—M…

鸿蒙基础-常用组件与布局(ArkTS)

实现“登录”页面 本节主要介绍“登录”页面的实现&#xff0c;页面使用Column容器组件布局&#xff0c;由Image、Text、TextInput、Button、LoadingProgress等基础组件构成。 // LoginPage.ets Entry Component struct LoginPage {...build() {Column() {Image($r(app.media…

isp代理/双isp代理/数据中心代理的区别?如何选择?

本文我们来详细科普一下几种不同的代理类型&#xff1a;isp代理/双isp代理/数据中心代理&#xff0c;了解他们的区别&#xff0c;选择更适合自己的代理类型。 在讲述这几种代理类型之前&#xff0c;我们先复习一下代理大类有哪几种。 一、机房代理和非机房代理 在做代理ip选…

js中Math.min(...arr)和Math.max(...arr)的注意点

当arr变量为空数组时&#xff0c;这两个函数和不传参数时的结果是一样的 Math.max() // -Infinity Math.max(...[]) // -InfinityMath.min() // Infinity Math.min(...[]) // Infinity

广东mes生产管理系统

mes生产管理系统是面向制造企业执行层的生产信息化管理系统。它可以帮助企业实现制造数据管理、计划排程管理、生产调度管理、库存管理、质量管理、人力资源管理、工作与设备管理、工具工装管理、采购管理、成本管理、项目看板管理、生产过程控制、底层数据集成分析、上层数据集…

ip addr和ifconfig

ip addr可以显示更多信息&#xff0c;包括为启动的网络驱动如wlan&#xff0c;而ifocnfig只显示在线的驱动。若wlan是down的&#xff0c;则ip addr会显示信息&#xff0c;ifconfig不会显示信息。 ip addr: ifconfig:

android内存管理机制概览

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、相关概念3.1 垃圾回收3.2 应用内存的分配与回…

九、Shell 只读变量和删除变量

一、只读变量 在 Shell 脚本中&#xff0c;使用 readonly 关键字声明只读变量&#xff0c;只读变量被赋值后&#xff0c;就不能再被修改或重新赋值。这对于脚本中的某些值不被意外修改非常有用。 以下是一个示例&#xff0c;演示如何在 Shell 脚本中使用只读变量 #!/bin/bash…

浅谈故障注入目的与优势

故障注入是一种有意识地向系统或软件中引入错误、故障或异常的测试技术。这种方法旨在评估系统在异常情况下的表现&#xff0c;并帮助发现潜在的问题&#xff0c;以便在生产环境中减少故障的风险。本文将介绍故障注入目的与优势有哪些! 故障注入的主要目的是在安全的环境下评估…

Java中的内部类、枚举

内部类、枚举 内部类成员内部类静态内部类局部内部类&#xff08;不重要&#xff09;匿名内部类&#xff08;重要&#xff09;什么是匿名内部类使用场景 枚举类什么是枚举类枚举类的特点枚举类提供的一些额外API拓展&#xff1a;抽象枚举使用枚举类实现单例设计模式 常见应用场…

Django之按钮(actions)

开篇就是道歉&#xff0c;哈哈哈哈&#xff0c;托更了好久好久&#xff0c;最近太忙了没啥时间更新&#xff0c;各位看官有催更的阔以给我私信哇&#xff0c;希望各位看官给个三连&#xff01;&#xff01;&#xff01;&#x1f60d;&#x1f60d;&#x1f60d;&#x1f60d; …

python:改进型鳟海鞘算法(SSALEO)求解23个基本函数

一、改进型鳟海鞘算法SSALEO 改进型鳟海鞘算法&#xff08;SSALEO&#xff09;由Mohammed Qaraad等人于2022年提出。 参考文献&#xff1a;M. Qaraad, S. Amjad, N. K. Hussein, S. Mirjalili, N. B. Halima and M. A. Elhosseini, "Comparing SSALEO as a Scalable Larg…

部署谷歌的Gemini大模型

前言 本文将介绍如何使用Docker、Docker-Compose私有化部署谷歌的Gemini大模型&#xff0c;以及没有服务器的情况下如何使用Vercel来部署。 Demo: 使用新加坡云服务器部署&#xff1a;Gemini Pro Chat (snowice.eu.org) 使用Vercel部署&#xff1a;Gemini Pro Chat (snowice.eu…

NGUI基础-三大基础组件之Root组件

NGUI NGUI&#xff08;Next-Gen UI&#xff09;是一款用于Unity游戏引擎的UI插件&#xff0c;它提供了一套功能强大、灵活易用的界面开发工具。在NGUI中&#xff0c;Root&#xff08;根节点&#xff09;是一个重要的概念。 基础组件之Root Root是NGUI中的最高层级节点&#…