Redis数据类型 — String

目录

String类型的内部编码

存储字符串采用两种编码方式的优缺点

选择SDS的原因

存储整数型采用OBJ_ENCODING_INT的原因


String 类型的底层的数据结构实现主要是 long 和 SDS(简单动态字符串)

数据结构:SDSicon-default.png?t=N6B9https://blog.csdn.net/weixin_44415582/article/details/131709666?spm=1001.2014.3001.5501

String类型的内部编码

类型的内部编码(encoding)有 3 种 :int、raw和 embstr

存储数据为字符串时

  • 其基本编码方式是RAW,基于简单动态字符串(SDS)实现,存储上限为512mb。但RAW会通过调用两次内存分配函数来分别分配两块空间来保存redisObjectSDS
  • 在redis 5.0之后,如果存储的SDS长度小于44字节,则会采用EMBSTR编码会通过一次内存分配函数来分配一块连续的内存空间来保存redisObjectSDS

存储的字符串是整数值时

  • 其大小在LONG_MAX范围内,则会采用INT编码:直接将数据保存在RedisObject的ptr指针位置(刚好8字节针对64位系统),不再需要SDS了。

存储字符串采用两种编码方式的优缺点

优点:

  • embstr编码将创建字符串对象所需的内存分配次数从 raw 编码的两次降低为一次;
  • 释放 embstr编码的字符串对象同样只需要调用一次内存释放函数;
  • 因为embstr编码的字符串对象的所有数据都保存在一块连续的内存里面可以更好的利用 CPU 缓存提升性能。

embstr 也有缺点

  • 如果字符串的长度增加时,需要重新分配内存,整个redisObject和sds都需要重新分配空间,所以embstr编码的字符串对象实际上是只读的,redis没有为embstr编码的字符串对象编写任何相应的修改程序。当我们对embstr编码的字符串对象执行任何修改命令(例如append)时,程序会先将对象的编码从embstr转换成raw,然后再执行修改命令。

选择SDS的原因

  • SDS 不仅可以保存文本数据,还可以保存二进制数据
  • SDS 获取字符串长度的时间复杂度是 O(1)
  • Redis 的 SDS API 是安全的,拼接字符串不会造成缓冲区溢出

存储整数型采用OBJ_ENCODING_INT的原因

  • 在对string进行加、减等操作的时候,如果它内部是OBJ_ENCODING_INT编码,那么可以直接进行加减操作
  • 如果它内部是OBJ_ENCODING_RAW或OBJ_ENCODING_EMBSTR编码,那么Redis会先试图把sds存储的字符串转成long型,如果能转成功,再进行加减操作。

原因:对⼀个内部表示成long型的string执行append, setbit, getrange这些命令,针对的仍然是string的值(即十进制表示的字符串),而不是针对内部表⽰的long型进行操作
若不进行转换,情景如下:字符串”32”,如果按照字符数组来解释,它包含两个字符,它们的ASCII码分别是0x33和0x32。当我们执行命令【setbit key 7 0】的时候,相当于把字符0x33变成了0x32,这样字符串的值就变成了”22”。⽽如果将字符串”32”按照内部的64位long型来解释,那么它是0x0000000000000020,在这个基础上执行setbit位操作,结果就完全不对了。因此,在这些命令的实现中,会把long型先转成字符串再进行相应的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值