版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Sophisticated_/article/details/84543441
基于Redis5.0
字符串对象
字符串对象的编码可以是 int
、 raw
或者 embstr
- 如果一个字符串对象保存的是整数值, 并且这个整数值可以用
long
类型来表示, 那么字符串对象会将整数值保存在字符串对象结构的ptr
属性里面(将void*
转换成long
), 并将字符串对象的编码设置为int
- 如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度大于
44
字节(#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
), 那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值, 并将对象的编码设置为raw
- 如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度小于等于
44
字节, 那么字符串对象将使用embstr
编码的方式来保存这个字符串值
embstr
编码是专门用于保存短字符串的一种优化编码方式, 这种编码和 raw
编码一样, 都使用 redisObject
结构和 sdshdr
结构来表示字符串对象, 但 raw
编码会调用两次内存分配函数来分别创建 redisObject
结构和 sdshdr
结构, 而 embstr
编码则通过调用一次内存分配函数来分配一块连续的空间, 空间中依次包含 redisObject
和 sdshdr
两个结构
以下命令创建了一个 embstr
编码的字符串对象作为 msg
键的值
redis> SET msg "hello"
OK
redis> OBJECT ENCODING msg
"embstr"
编码的转换
对于 int
编码的字符串对象来说, 如果我们向对象执行了一些命令, 使得这个对象保存的不再是整数值, 而是一个字符串值, 那么字符串对象的编码将从 int
变为 raw
redis> SET number 10086
OK
redis> OBJECT ENCODING number
"int"
redis> APPEND number " is a good number!"
(integer) 23
redis> GET number
"10086 is a good number!"
redis> OBJECT ENCODING number
"raw"
Redis 没有为 embstr
编码的字符串对象编写任何相应的修改程序 (只有 int
编码的字符串对象和 raw
编码的字符串对象有这些程序), 所以 embstr
编码的字符串对象实际上是只读的: 当我们对 embstr
编码的字符串对象执行任何修改命令时, 程序会先将对象的编码从 embstr
转换成 raw
, 然后再执行修改命令; 因为这个原因, embstr
编码的字符串对象在执行修改命令之后, 总会变成一个 raw
编码的字符串对象
redis> SET msg "hello world"
OK
redis> OBJECT ENCODING msg
"embstr"
redis> APPEND msg " again!"
(integer) 18
redis> OBJECT ENCODING msg
"raw"
字符串命令的实现
因为字符串键的值为字符串对象, 所以用于字符串键的所有命令都是针对字符串对象来构建的,下表列举了其中一部分字符串命令, 以及这些命令在不同编码的字符串对象下的实现方法
命令 | int 编码的实现方法 | embstr 编码的实现方法 | raw 编码的实现方法 |
---|---|---|---|
SET | 使用 int 编码保存值。 | 使用 embstr 编码保存值。 | 使用 raw 编码保存值。 |
GET | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 然后向客户端返回这个字符串值。 | 直接向客户端返回字符串值。 | 直接向客户端返回字符串值。 |
APPEND | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此操作。 | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此操作。 | 调用 sdscatlen 函数, 将给定字符串追加到现有字符串的末尾。 |
INCRBYFLOAT | 取出整数值并将其转换成 long double 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 | 取出字符串值并尝试将其转换成 long double 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 如果字符串值不能被转换成浮点数, 那么向客户端返回一个错误。 | 取出字符串值并尝试将其转换成 long double 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 如果字符串值不能被转换成浮点数, 那么向客户端返回一个错误。 |
INCRBY | 对整数值进行加法计算, 得出的计算结果会作为整数被保存起来。 | embstr 编码不能执行此命令, 向客户端返回一个错误。 | raw 编码不能执行此命令, 向客户端返回一个错误。 |
DECRBY | 对整数值进行减法计算, 得出的计算结果会作为整数被保存起来。 | embstr 编码不能执行此命令, 向客户端返回一个错误。 | raw 编码不能执行此命令, 向客户端返回一个错误。 |
STRLEN | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 计算并返回这个字符串值的长度。 | 调用 sdslen 函数, 返回字符串的长度。 | 调用 sdslen 函数, 返回字符串的长度。 |
SETRANGE | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此命令。 | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此命令。 | 将字符串特定索引上的值设置为给定的字符。 |
GETRANGE | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 然后取出并返回字符串指定索引上的字符。 | 直接取出并返回字符串指定索引上的字符。 | 直接取出并返回字符串指定索引上的字符。 |