redis底层数据结构

Redis 使用多种数据结构实现其核心功能,如 String 使用 SDS,提供 O(1) 的长度获取和二进制安全性。List 由 quicklist 替代 linkedlist 和 ziplist,兼顾效率和存储。Hash 可以用 ziplist 实现小型数据,大型数据则转换为 dict。Set 可用 intset 或 dict,ZSet 结合 ziplist 和 skiplist 实现高效排序。这些数据结构的设计优化了内存使用和操作速度。
摘要由CSDN通过智能技术生成

redis对外公开的有5种数据结构,分别是String,List,Hash,Set,ZSet。这几种底层分别用了不同的数据结构来实现。

redis介绍:

redis是一个开源的使用C语言编写的一个kv存储系统,是一个速度非常快的非关系内存数据库。它支持包括String、List、Set、Zset、hash五种数据结构。
与关系型数据库相比,redis的命令请求不需要经过查询分析器或查询优化器进行处理,也避免了更新数据时引起的随机读\写,这些慢操作。它直接读写内存中的数据,并且数据是按照一定的数据结构存储的。所以它的速度非常快。

 

Redis采用redisObjec结构来统一五种不同的数据类型,这样所有的数据类型就都可以以相同的形式在函数间传递而不用使用特定的类型结构。

typedef struct redisObject {
    unsigned type:4; //保存信息的类型(String,List,Set,Zset,Hash)
    unsigned encoding:4;//保存信息的编码方式(底层数据结构)
    unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
    int refcount;//引用次数
    void *ptr;//保存的指针
} robj;
/* Object types */
#define OBJ_STRING 0
#define OBJ_LIST 1
#define OBJ_SET 2
#define OBJ_ZSET 3
#define OBJ_HASH 4

/* Objects encoding. Some kind of objects like Strings and Hashes can be
 * internally represented in multiple ways. The 'encoding' field of the object
 * is set to one of this fields for this object. */
#define OBJ_ENCODING_RAW 0     /* Raw representation */
#define OBJ_ENCODING_INT 1     /* Encoded as integer */
#define OBJ_ENCODING_HT 2      /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6  /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */

 

String:

由于redis是C语言写的,C语言并没有实现好的字符串类型,是用指针或则char数组实现的,C语言字符串结尾是以'\0'来标识。redis自定义了一种自定义结构,SDS(动态字符串)。

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

SDS的性质:

1.C 语言的字符串不会记录自己的长度,而是需要进行遍历获得,时间复杂度为 O(n) ,而 SDS 已经封装了 len 属性,直接读取 len 的值就可以获得长度,不需要遍历,时间复杂度 O(1) 。 
2.二进制安全的(C语言是以\0来表示字符串结束的),如果二进制中有 \0 会结束字符串。所以redis是可以存储图片和视频的。
3. 如果修改后的 SDS 长度 len 小于 1MB,那么程序分配和 len 属性相等的未使用空间,此时 free 和 len 的值相同。所以此时数组的实际长度为 free + len + 1byte(额外的空字符 1 个字节)。 
4. 如果修改后的 SDS 长度大于 1MB,那么程序分配 1MB 的未使用空间。实

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值