Redis String

对于Redis数据库保存的键值对来说,键总是一个字符串对象,而值可以是字符串对象,列表对象,哈希对象,集合对象或者有序集合对象中的其中一种。

Redis中有很多地方都使用了字符串,例如所有的key,String类型的value,Redis自己定义了简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。在 Redis 里面, C 字符串只会作为字符串字面量(string literal), 用在一些无须对字符串值进行修改的地方, 比如打印日志:

redisLog(REDIS_WARNING,"Redis is now ready to exit, bye bye...");

Redis SDS介绍

struct sdshdr{
    //记录buf数组中已使用字节的数量
    //等于SDS所保存的字符串的长度
    int len;
    //记录buf数组中未使用字节的数量
    int free;
    //字节数组,用于保存字符串
    char buf[];
}

redis存储String类型不带转义符 redis用string存储对象_数据库

更加详细的介绍参照Redis设计与实现。

redis存储String类型不带转义符 redis用string存储对象_redis_02

Redis键相关操作

redis存储String类型不带转义符 redis用string存储对象_字符串_03

Redis字符串相关操作

redis存储String类型不带转义符 redis用string存储对象_redis_04

Redis对象的类型与编码

Redis使用对象表示数据库中的键和值,每次当我们在Redis的数据库中新创建一个键值对时,我们至少创建两个对象,一个对象用作键值对的键,一个对象用作键值对的值。

以下SET命令在数据库中创建了一个新的键值对,其中键值对的键时包含了字符串值 "msg" 的对象,而键值对的值则是一个包含了字符串的值"hello word"的对象,Redis中每个对象都由一个redisObject结构表示,该结构中和保存数据有关的三个属性分别是type属性、encoding属性,ptr属性

typedef struct redisObject{
    //类型
    unsigned type:4;
    //编码
    unsigned encoding:4;
    //指向底层实现数据结构的指针
    void *ptr;
}robj;

type属性记录了对象的类型,这个属性的值可以是下图中列表的某一个

redis存储String类型不带转义符 redis用string存储对象_Redis_05

对象的ptr指针指向对象的底层实现数据结构,而这些数据结构有对象的encoding属性决定。encoding属性记录了对象所使用的编码,也即是说这个对象使用了什么数据结构作为对象的底层实现。

redis存储String类型不带转义符 redis用string存储对象_redis_06

每种类型的对象都至少使用了两种不同的编码,

redis存储String类型不带转义符 redis用string存储对象_redis_07

Redis字符串对象的编码可以是intrawembstr

如果一个字符串对象保存的是整数值, 并且这个整数值可以用 long 类型来表示, 那么字符串对象会将整数值保存在字符串对象结构的 ptr属性里面(将 void* 转换成 long ), 并将字符串对象的编码设置为 int

redis存储String类型不带转义符 redis用string存储对象_字符串_08

如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度大于 39 字节, 那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值, 并将对象的编码设置为 raw

举个例子, 如果我们执行以下命令, 那么服务器将创建一个如图 8-2 所示的 raw 编码的字符串对象作为 story 键的值:

redis存储String类型不带转义符 redis用string存储对象_数据库_09

如果字符串对象保存的是一个字符串的值,并且这个字符串的值的长度小于等于39字节,那么字符串对象将使用empstr编码方式来保存这个字符串的值。

embstr 编码是专门用于保存短字符串的一种优化编码方式, 这种编码和 raw 编码一样, 都使用 redisObject 结构和 sdshdr 结构来表示字符串对象, 但 raw 编码会调用两次内存分配函数来分别创建 redisObject 结构和 sdshdr 结构, 而 embstr 编码则通过调用一次内存分配函数来分配一块连续的空间, 空间中依次包含 redisObjectsdshdr 两个结构。

mbstr 编码的字符串对象在执行命令时, 产生的效果和 raw 编码的字符串对象执行命令时产生的效果是相同的, 但使用 embstr 编码的字符串对象来保存短字符串值有以下好处:

  1. embstr 编码将创建字符串对象所需的内存分配次数从 raw 编码的两次降低为一次。
  2. 释放 embstr 编码的字符串对象只需要调用一次内存释放函数, 而释放 raw 编码的字符串对象需要调用两次内存释放函数。
  3. 因为 embstr 编码的字符串对象的所有数据都保存在一块连续的内存里面, 所以这种编码的字符串对象比起 raw 编码的字符串对象能够更好地利用缓存带来的优势。

redis存储String类型不带转义符 redis用string存储对象_Redis_10


String对象的相关操作针对不同编码的具体实现

redis存储String类型不带转义符 redis用string存储对象_键值对_11