Redis学习笔记 - 字符串对象

参考:<<Redis设计与实现>>

  • 注:这本书是基于Redis3.0版本写的,和后面的版本有点差异

字符串对象的编码可以是 int、embstr 或 raw

  • 如果一个字符串对象保存的是整数值,并且可以用long类型来表示,那么就会将整数值赋值给字符串对象结构里的ptr属性,以及将字符串对象的编码设置为int。
  • 如果保存的是字符串,并且这个字符串值的长度大于39字节,那么字符串对象将使用SDS(简单动态字符串)保存,并将编码设置为raw。
  • 如果保存的是字符串,并且这个字符串的长度小于等于39字节,那么字符串对象使用embstr编码方式来保存字符串值。

注:3.2版本开始,改为了以44字节作为临界值,原因是sdshdr结构改了,占用了更少的字节,可以参考下面博客的解释:

字符串对象保存各类型值的编码方式如下表所示:

编码
可以用 long 类型保存的整数int
可以用 long double 类型保存的浮点数embstr 或 raw
字符串值,或超过long类型范围的整数,或超过long double类型范围的浮点数embstr 或 raw

一、字符串对象的编码

1.1 int编码的字符串对象

int编码的字符串对象,前提是整数,并且整数值在long类型范围内,否则仍然当作字符串来保存,int编码如下图所示:
int编码的字符串对象
示例:
使用object endocing key查看对象使用的编码

redis> set num 10086
redis> object encoding num
"int"
1.2 raw编码保存的字符串对象

使用redisObject结构和sdshdr结构来表示字符串对象。

示例:
保存一个长度大于39字节的字符串,使用object encoding key命令查看使用的编码,可以看出使用了raw编码,

redis> set str "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
OK
redis> strlen str
(integer) 52
reeis> object encoding str
"raw"

raw编码的字符串对象如下图所示:
raw编码的字符串对象

1.3 embstr编码保存的字符串对象

embstr编码是专门用于保存短字符串的一种优化编码方式,同样使用redisObject结构和sdshdr结构来表示字符串对象。

使用embstr编码的字符串对象保存短字符串的优点:

  • embstr编码将创建字符串对象只需要调用一次内存分配函数创建连续的redisObject和sdshdr结构,而raw编码会调用两次内存分配函数分别创建redisObject和sdshdr结构
  • 释放embstr编码的字符串只需要调用一次内存释放函数,释放raw编码需要调用两次
  • embstr编码的字符串对象所有数据保存在一块连续的内存里,这种编码方式比起raw编码能更好地利用缓存带来的优势

embstr创建的内存块结构如下图所示:
embstr创建的内存块结构

1.4 浮点数使用的编码

可以用 long double 类型表示的浮点数在Redis中作为字符串值来保存的。

注:若超过double类型范围,则根据长度使用embstr或raw编码保存。

保存一个浮点数时,程序会先把浮点数转化为字符串,然后再保存转换后的字符串值。
在执行某些操作时,程序会将字符串值转换为浮点数,进行相关操作,再将操作所得的浮点数转换为字符串值进行保存。

示例:

redis> set pi 3.14
OK
redis> object encoding pi
"embstr"
redis> incrbyfloat pi 2.0
"5.14"
redis> object encoding pi
"embstr"

二、编码的转换

int编码和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。

2.1 int -> raw

int编码的字符串对象执行了某些操作,如 APPEND命令,拼接一个字符串值,那么字符串对象的编码就会从 int 变为 raw。

示例:

redis> set num 10086
OK
redis> object encoding num
"int"
redis> append num " is a number"
(integer) 17
redis> get num
"10086 is a number"
redis> object encoding num
"raw"
2.2 embstr -> raw

Redis没有为embstr编码的字符串对象提供修改程序,所以当执行修改操作时,先要转换为 raw 编码,再执行修改操作。所以执行修改命令后,会变成 raw编码 的字符串对象。

注:

  • 只有int和raw编码的字符串对象才有相应的修改程序
  • embstr编码的字符串对象实际上是只读的

示例:

redis> set str "hello world"
OK
redis> object encoding str
"embstr"
redis> append str " !"
(integer) 13
redis> object encoding str
"raw"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值