大家好 我是积极向上的湘锅锅💪💪💪
Redis 数据类型String,List,Set,ZSet,Hash详解
1. SDS(简单动态字符串)
SDS是Redis的string结构主要构成,本质是结构体(java里面是对象)
查看源码
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* buf保存的字节数 */
uint8_t alloc; /* buf已申请的字节数 */
unsigned char flags; /* 不同的SDS类型 */
char buf[];
};
因为sdshdr5太小已经弃用,所以以sdshdr8 举例
当然不止这一种 还有sdshdr16,sdshdr832,sdshdr64,感兴趣的也可以看源码;
区别就是 sdshdr8最大保存为2的8次方-1,依次类推,sdshdr16,sdshdr832可以保存的bit逐渐增大
接下来看个例子 比如说一个“name”的sds结构如下
可以很清晰的看到长度为4,分配的字节数为4,flags为1(对应sdshdr8 ),buf数组里面存放的是name的字符串数组
那我们知道字符串数组是以\0结尾来表示结束,而这里是以len的长度来读取,也就是说len多长,我就读取多少个字符
如果不这样做,设想如果中间有\0字符,那就直接读取结束了,是不符合一个数据安全性的
SDS的动态扩容
如果想要在字符串后面追加字符串,首先会申请一个新的内存空间
- 如果新字符串小于1M,则新空间为扩展后的空间*2+1,
- 如果新字符串大于1M,则新空间为扩展后的空间+1M+1
以上过程称为内存的预分配
也就是说比如一个alloc为2的sds,加入一个长度为4的字符串,则最后alloc变为12,其中+1是最后的\0,alloc是不包含\0的
SDS的优点
- 获取字符串长度的时间复杂度为O(1);
- 动态扩容
- 二进制安全
- 减少内存分配的次数
2. Intset
看名字就知道是啥了,对没错就是整数类型的set,而且还具备长度可变,内部自动有序
源码:
typedef