redis:String字符串命令和内部编码
文章目录
- 前言
- 一、 String字符串命令
- 常见命令
- SET
- GET
- MGET 和 MSET
- SETNX,SETEX,PSETEX
- 计数命令
- INCR
- INCRBY
- DECR
- DECRBY
- INCRBYFLOAT
- 其它命令
- APPEND
- GETRANGE
- SETRANGE
- STRLEN
- 二、内部编码
- 总结
个人主页 : 个人主页
个人专栏 : 《数据结构》 《C语言》《C++》《Linux》《网络》 《redis学习笔记》
文章目录
- 前言
- 一、 String字符串命令
- 常见命令
- SET
- GET
- MGET 和 MSET
- SETNX,SETEX,PSETEX
- 计数命令
- INCR
- INCRBY
- DECR
- DECRBY
- INCRBYFLOAT
- 其它命令
- APPEND
- GETRANGE
- SETRANGE
- STRLEN
- 二、内部编码
- 总结
前言
本文是作为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学习笔记