Redis是是以K-V的形式存储数据的.其中V的数据类型有多种,如String,List,Hash,Set,Zset等.而K的数据类型只是String.
在Redis中,无论哪种数据类型,其抽象模型都是redisObject,
typedef struct redisObject{
unsigned type:4;
unsigned encoding:4;
unsigned lru:Lru_BITS;
int refcount;
void *ptr;
} robj
其中:
- type--数据类型
- encoding:编码格式
- lru:时间戳
- redcount:引用计数
- ptr:指向实际的数据结构
对于String数据类型,ptr指向的数据结构就是sds.
sds是redis中自定义的数据结构,与c语言中字符串以空白字符结尾不同的是,sds对字符串类型做了扩展,有如下优点:
- 可以在O(1)时间获取到字符串的长度
- 可以存放空字符
- 是二进制安全,可以存放任意二进制数据
sds结构体可以分为sdshdr5,sdshdr8,sdshdr16,sdshdr32,sdshdr64
除了sdshdr5意外,其余几种结构体都维护了以下4个信息:
- len--字符串的长度
- alloc:已经申请的字符串长度
- flags--sds类型
- buf--字符串内容(数组)
sdshdr5中仅有flags和buf字符段.flags低3位代表sds类型,高5位代表字符串长度,并且sdshdr5是常量字符串,不支持扩容.
sds设计不同类型的原因是可以根据字符串的长度选择不同合适的len,alloc属性,最大限度地节省内存.
sds字符串的编码有三种,分别为EMBSTR,RAW,INT.
EMBSTR针对短字符串进行了优化,redisObject和sds在一块连续的内存空间之内(len<44>)
RAW针对长字符串(len>44) redisObject和sds在两块不同的内存区域.
INT针对整数型字符串并且长度小于等于20,将转为long long类型