redis:String字符串命令和内部编码

文章目录


个人主页 : 个人主页

个人专栏 : 《数据结构》 《C语言》《C++》《Linux》《网络》 《redis学习笔记》

文章目录


前言

本文是作为String字符串命令和内部编码的学习笔记


字符串类型是redis最基本的数据类型,redis中所有键的类型都是字符串类型,而且有其它几种数据结构都是在字符串类似基础上构建的(如列表,集合的元素类型都是字符串类型)。

redis中的字符串,直接就是按照二进制数据的方式存储的(不会做任何编码转换),不仅仅可以存储文本数据,还可以存储整数,JSON,xml,二进制数据(图片,视频,音频)。

redis对于string类型,限制大小最大是512M,毕竟redis是单线程模式,希望进行的操作都可以快速完成

一、 String字符串命令

常见命令

SET

将string类型的value设置到key中。如果 key 不存在,创建新的键值对;如果 key 存在,则让新的 value 覆盖旧的 value ,可能会改变原来的数据类型,原来的 key 的 ttl 也会失效。

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

返回值:设置成功,返回OK;如果由于 SET 指定了 NX 或者 XX 但条件不满足,SET不会执行,并返回 nil。

时间复杂度:O(1)

选项:

  • EX second:使用秒作为单位设置 key 的过期时间
  • PX milliseconds:使用毫秒作为单位设置 key 的过期时间
  • NX:只在 key 不存在时才进行设置,即如果 key 之前已经存在,设置不执行
  • XX:只在 key 存在时才进行设置,即如果 key 之前不存在,设置不执行

redis 文档给出的语法格式说明:[ ] 相当于一个独立单元,表示可选项;其中 | 表示 或者 的意思,多个只能出现一个,[ ] 和 [ ] 之间,可以同时存在。


GET

获取 key 对应的 value。如果 key 不存在,返回 nil;如果 value 的数据类型不是 string,会报错。

GET key

返回值:key存在时,返回对应的 value;key 不存在时,返回 nil。

时间复杂度:O(1)


MGET 和 MSET

MGET

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

MGET key [key ...]

返回值:对应 value 的列表

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


MSET

一次性设置多个 key 的值

MSET key value [ key value ... ]

返回值:永远都是 OK

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


注意:

基本全局命令-键管理(1)中记录的,MGET / MSET 的效率 比 GET / SET 的效率高,但要注意,每次批量操作所发送的键的数量也不能太多,否则可能造成单一命令执行时间过长,导致 redis 阻塞(如一次查询10万个key)。


SETNX,SETEX,PSETEX

SETNX

设置 key-value 但只允许在 key 之前不存在的情况下

SETNX key value

返回值:1表示设置成功;0表示没有设置。


SETEX

设置key-value,并设置键的过期时间,单位为秒;如果键已经存在,旧的键会被覆盖。

SETEX key seconds value

返回值:成功,返回OK

时间复杂度:O(1)


PSETEX

设置key-value,并设置键的过期时间,单位为毫秒;如果键已经存在,旧的键会被覆盖。

PSETEX key milliseconds value

返回值:成功,返回OK

时间复杂度:O(1)


SET 和 SET NX 和 SET XX


redis针对 set 的一些常见用法,进行了缩写;就是为了让操作更符合人的直觉(使用者的门槛就越低)。

编程语言中,很多关键词,都和自然语言相关(英语)。


计数命令

INCR

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

INCR key

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

时间复杂度:O(1)


注意:

如果有多个客户端同时针对同一个key 进行 incr 操作,会不会引起"线程安全"问题?

很明显不会,由于 redis 处理命令时,是单线程模型。多个请求同时到达redis服务器,也要先在队列排队,再等待redis服务器一个一个的取出里面的命令执行。微观上看,redis服务器是串行/顺序执行这多个命令的


INCRBY

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

INCRBY key decrement

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

时间复杂度:O(1)


注意:

INCRBY 可以通过加一个负数,实现减的效果

但没必要这样操作,我们有DECRBY命令实现减法;也是为了符合人的直觉。


DECR

将 key 对应的string 表示的数字减一。如果key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是一个整数 或者 超出了64位有符号整数,则报错

DECR key

返回值:integer类型减完的数值

时间复杂度:O(1)


DECRBY

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

DECRBY key decrement

返回值:integer 类型的减完后的数值

时间复杂度:O(1)


INCRBYFLOAT

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

INCRBYFLOAT key increment

返回值:加/减完后的数值

时间复杂度:O(1)

没有提供对应的减法版本。


其它命令

APPEND

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

APPEND KEY VALUE

返回值:追加完成之后 string 的长度

时间复杂度:O(1),追加的字符串一般长度较短,可以视为 O(1)


注意:

append返回值,长度的单位是什么?字节还是字符?

redis的字符串,不会对字符编码做任何处理,我们使用 xshell 终端(默认字符编码是 utf8 ),向redis中的字符串写入 "你好" 两个汉字,看append的返回值是 2 还是 6。

append的返回值是6,而在 utf8 中,一个汉字通常是 3个字节。所以 append 的返回值 是 字节。

在启动 redis 客户端时,加上 --raw选项,可以使 redis 客户端 能够自动的把二进制数据尝试翻译。


GETRANGE

返回 key 对应的 string 的子串,由start 和 end确定(左闭右闭,闭区间)。

GETRANGE key start end

返回值:string 类型的子串

时间复杂度:O(N),N 为[ start, end ]区间的长度。由于 string 通常比较短,可以视为 O(1)

start 和 end 可以使用负数表示倒数,如 -1 代表 倒数第一个字符,-2代表倒数第二个。超出范围的偏移量会根据 string 的长度调整为 正确的值。


注意:

如果字符串中保存是汉字,此时进行字符串切分,可能得到不完整的汉字

启动 redis 客户端时,加上 --raw选项。redis 客户端 会把二进制数据尝试翻译。


SETRANGE

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

SETRANGE key offset value

返回值:替换后的string的长度

时间复杂度:O(N),N为 value 的长度,由于一般 value 比较短,通常视为 O(1)


注意:

如果 key 对应 的value是一个汉字,进行setrange的时候,可能会出问题

如果 key 对应的 value 不存在,进行 setrange时,会将offset之前的内容填充为0X00


STRLEN

获取 key 对应的 string的长度。当 key 对应的value 不是 string时,报错

STRLEN key

返回值:string的长度。当key不存在时,返回0

时间复杂度:O(1)


注意:

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

使用 xshell 终端(默认字符编码是 utf8 ),向redis中的字符串写入 "你好" 两个汉字。

二、内部编码

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

  • int:8个字节的长整型
  • embstr:压缩字符串,适用于表示比较短的字符串
  • raw:普通字符串,适用于表示更长的字符串,只是单纯的持有字节数组

redis会根据当前值的类型和长度动态决定使用那种内部编码实现

redis存储小数,本质还是当做字符串存储

这样,对于小数,每次进行算术运算的时候,都需要把字符串转成小数,进行运算,结果再转回字符串保存


总结

以上就是我是redis学习笔记

相关推荐
cr7xin29 分钟前
缓存三大问题及解决方案
redis·后端·缓存
TDengine (老段)1 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
qq7422349841 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
姚远Oracle ACE2 小时前
Oracle 如何计算 AWR 报告中的 Sessions 数量
数据库·oracle
Dxy12393102162 小时前
MySQL的SUBSTRING函数详解与应用
数据库·mysql
码力引擎2 小时前
【零基础学MySQL】第十二章:DCL详解
数据库·mysql·1024程序员节
杨云龙UP3 小时前
【MySQL迁移】MySQL数据库迁移实战(利用mysqldump从Windows 5.7迁至Linux 8.0)
linux·运维·数据库·mysql·mssql
l1t3 小时前
利用DeepSeek辅助修改luadbi-duckdb读取DuckDB decimal数据类型
c语言·数据库·单元测试·lua·duckdb
睡前要喝豆奶粉3 小时前
在.NET Core Web Api中使用redis
redis·c#·.netcore
安当加密3 小时前
Nacos配置安全治理:把数据库密码从YAML里请出去
数据库·安全