🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
在`Redis`中所有的数据类型都是将对应的数据结构进行了再一次包装,创建了一个字典对象来存储,`sds`也不例外。每次创建一个`key-value`键值对,`Redis`都会创建两个对象,一个是键对象,一个是值对象。而且需要注意的是**在`Redis`中,值对象并不是直接存储,而是被包装成`redisObject`对象**,并同时将键对象和值对象通过`dictEntry`对象进行封装,如下就是一个`dictEntry`对象: ~~~c typedef struct dictEntry { void *key;//指向key,即sds union { void *val;//指向value uint64_t u64; int64_t s64; double d; } v; struct dictEntry *next;//指向下一个key-value键值对(哈希值相同的键值对会形成一个链表,从而解决哈希冲突问题) } dictEntry; ~~~ `redisObject`对象的定义为: ~~~c typedef struct redisObject { unsigned type:4;//对象类型(4位=0.5字节) unsigned encoding:4;//编码(4位=0.5字节) unsigned lru:LRU_BITS;//记录对象最后一次被应用程序访问的时间(24位=3字节) int refcount;//引用计数。等于0时表示可以被垃圾回收(32位=4字节) void *ptr;//指向底层实际的数据存储结构,如:sds等(8字节) } robj; ~~~ 当我们在`Redis`客户端中执行命令`set name lonely_wolf`,就会得到下图所示的一个结构(省略了部分属性): ![](https://img.kancloud.cn/8a/c0/8ac0d1384b2f2d81a1981ddbdeba1335_614x315.png) 看到这个图想必大家会有疑问,这里面的`type`和`encoding`到底是什么呢?其实这两个属性非常关键,`Redis`就是通过这两个属性来识别当前的`value`到底属于哪一种基本数据类型,以及当前数据类型的底层采用了何种数据结构进行存储。