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学习笔记

相关推荐
p@nd@9 分钟前
Oracle筑基篇-调度算法-LRU的引入
数据库·oracle·操作系统·lru
来一杯龙舌兰21 分钟前
【MongoDB】使用 MongoDB 存储日志、审批、MQ等数据的案例及优点
数据库·mongodb
技术路上的苦行僧22 分钟前
分布式专题(8)之MongoDB存储原理&多文档事务详解
数据库·分布式·mongodb
孤独的履行者29 分钟前
入门靶机:DC-1的渗透测试
数据库·python·网络安全
wy02_37 分钟前
MySQL-MVCC(多版本并发控制)
数据库·mysql
on the way 1232 小时前
Redisson锁简单使用
redis
NY62 小时前
mysql运维篇笔记——日志,主从复制,分库分表,读写分离
数据库·sql
潜洋2 小时前
Spring Boot 教程之三十六:实现身份验证
java·数据库·spring boot
科马2 小时前
【Redis】缓存
数据库·redis·spring·缓存
LuiChun3 小时前
Django 模板分割及多语言支持案例【需求文档】-->【实现方案】
数据库·django·sqlite