@(Redis 笔记)[Redis, 数据库]
Redis 对象
-
Redis 中使用对象表示数据库中的键和值,每创建一个键值对,至少创建 2 个对象。
-
对象的
type属性记录了对象的类型,有 5 种:类型常量 对象 REDIS_STRING 字符串对象 REDIS_LIST 列表对象 REDIS_HASH 哈希对象 REDIS_SET 集合对象 REDIS_ZSET 有序集合对象 -
编码与底层实现:对象的
ptr指针指向对象的底层实现数据结构,数据结构由对象的encoding属性决定。encoding属性记录了对象所使用的编码,即该对象是用什么类型的数据结构决定的。类型常量 编码 对象 REDIS_STRINGREDIS_ENCODING_INT整数值实现的字符串对象 REDIS_STRINGREDIS_ENCODING_EMBSTR使用 embstr编码的简单动态字符串实现的字符串对象REDIS_STRINGREDIS_ENCODING_RAW简单动态字符串实现的 字符串对象 -- -- -- REDIS_LISTREDIS_ENCODING_ZIPLIST使用压缩列表实现的列表对象 REDIS_LISTREDIS_ENCODING_LINKEDLIST使用双端链表列表对象 -- -- -- REDIS_HASHREDIS_ENCODING_ZIPLIST使用压缩列表实现的哈希对象 REDIS_HASHREDIS_ENCODING_HT使用字典实现的哈希对象 -- -- -- REDIS_SETREDIS_ENCODING_INTSET使用整数实现的集合对象 REDIS_SETREDIS_ENCODING_HT使用字典实现的集合对象 -- -- -- REDIS_ZSETREDIS_ENCODING_ZIPLIST使用压缩列表实现的有序集合对象 REDIS_ZSETREDIS_ENCODING_SKIPLIST使用跳跃表实现的有序集合对象
简单动态字符串 SDS
- Redis 中没有采用 C 字符串,而是自己构建了 SDS
- C 字符串应用在一些字符串常量值,不需要修改
sds.h/sdshdr结构表示一个SDS:
// 总长度为 len + free + 1, 1 用于存储 /0
struct sdshdr {
// 1. sds 中已使用的字节
int len;
// 2. sds 中空闲的字节
int free;
// 3. 字符串
char buf[];
}
SDS与C string区别:
SDS获取字符串长度的时间为O(1)SDS记录字符串长度,可以防止缓冲区溢出- 减少修改字符串时,导致的内存重分配次数:C 字符串增加元素而数组大小不够时,需要先扩展数组大小,否则会产生内存溢出。在删除元素时,若忘记释放内存,则会导致内存溢出。
SDS通过len与free,解除了字符串长度与底层数组长度之间的关系。可以 实现空间预分配 与 惰性空间释放 两种优化策略。 - 空间与分配:扩展
SDS时,会同时分配修改所需要的空间和额外未使用的空间。进行修改之后,SDS的len将变成13字节, 那么程序也会分配13字节的未使用空间。 - 惰性空间释放:缩短
SDS时,不会直接回收内存,而是用free来收集空闲区域。 - 二进制安全:
C字符串只能保存文本数据,会忽略\0以后的内容。 - 兼容部分 C 字符串函数