@(Redis 笔记)[Redis, 数据库]
Redis 对象
-
Redis 中使用对象表示数据库中的键和值,每创建一个键值对,至少创建 2 个对象。
-
对象的
type
属性记录了对象的类型,有 5 种:类型常量 对象 REDIS_STRING 字符串对象 REDIS_LIST 列表对象 REDIS_HASH 哈希对象 REDIS_SET 集合对象 REDIS_ZSET 有序集合对象 -
编码与底层实现:对象的
ptr
指针指向对象的底层实现数据结构,数据结构由对象的encoding
属性决定。encoding
属性记录了对象所使用的编码,即该对象是用什么类型的数据结构决定的。类型常量 编码 对象 REDIS_STRING
REDIS_ENCODING_INT
整数值实现的字符串对象 REDIS_STRING
REDIS_ENCODING_EMBSTR
使用 embstr
编码的简单动态字符串实现的字符串对象REDIS_STRING
REDIS_ENCODING_RAW
简单动态字符串实现的 字符串对象 -- -- -- REDIS_LIST
REDIS_ENCODING_ZIPLIST
使用压缩列表实现的列表对象 REDIS_LIST
REDIS_ENCODING_LINKEDLIST
使用双端链表列表对象 -- -- -- REDIS_HASH
REDIS_ENCODING_ZIPLIST
使用压缩列表实现的哈希对象 REDIS_HASH
REDIS_ENCODING_HT
使用字典实现的哈希对象 -- -- -- REDIS_SET
REDIS_ENCODING_INTSET
使用整数实现的集合对象 REDIS_SET
REDIS_ENCODING_HT
使用字典实现的集合对象 -- -- -- REDIS_ZSET
REDIS_ENCODING_ZIPLIST
使用压缩列表实现的有序集合对象 REDIS_ZSET
REDIS_ENCODING_SKIPLIST
使用跳跃表实现的有序集合对象
简单动态字符串 SDS
- Redis 中没有采用 C 字符串,而是自己构建了 SDS
- C 字符串应用在一些字符串常量值,不需要修改
sds.h/sdshdr
结构表示一个SDS
:
// 总长度为 len + free + 1, 1 用于存储 /0struct 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 字符串函数