前面已经介绍了一些redis的基本数据结构,本章则继续介绍,构建于底层数据结构之上的,“对象”,这一概念。之后再谈一谈redis服务器和客户端中数据库的基本组织结构。
redisObject
Basic
先用一张图来进行总体的概括,如下图所示。

认识redis对象的第一步,就是要搞明白为什么要定义这个概念。原则上,直接使用redis中基本的数据结构,比如说SDS,哈希表等等,我们就可以进行相应的数据存储了。所谓的redis对象,更像是一个抽象层,通过这层抽象,我们获得了一个很重要的能力,也就是相同的物理对象可以由不同的底层数据结构去实现。这是redis灵活性的重要体现。比如说,对于一个需要保存的值"123",显然,我们可以用一个字符串进行保存,也可以用一个整数去保存,但使用整数是更节省空间的,那么这个时候,我们就可以利用"redis对象"这个抽象,将"123"定义为一个REDIS_STRING,但这个REDIS_STRING到底是怎么去存储的,则交由系统去管理,我们不用再花费大量功夫去选择合适的数据结构,redis已经帮我们造好了轮子。
REDIS_STRING

对于REDIS_STRING对象,还是比较直观的。比如说“12”,那么它肯定是可以用一个int型变量来保存的,因此在底层直接使用int保存即可;而对于“12.43”,即使它是一个数字,但因为是浮点数,无法用int保存,且该value的长度较短,所以可以使用embstr来进行保存。embstr就是将redis对象和底层的sds整合到了一块空间中进行保存。(embed,嵌入)
明白了这一层意思,那么对于各个内置的关于REDIS_STRING的命令,则可以有效的进行理解了。比如先执行
SET testobj 1.23
,那么现在,testobj就是一个REDIS_STRING,且底层数据结构是REDIS_ENCODING_EMBSTR,然后我们可以执行一个INCRBYFLOAT testobj 1
,那么,就会先根据testobj的字符串值,转换成一个浮点数,浮点数加1之后,再转换为REDIS_ENCODING_EMBSTR,并对testobj进行更改。
- Attention:REDIS_STRING作为最基本的redis对象,它可以被嵌套在其他redis对象的底层结构之中。比如说对于REDIS_HT,其底层如果使用字典数据结构的话,字典的哈希表的每个键和值都是一个REDIS_STRING。
redisDb
如下,redisServer中的db指针就代表着redis数据库的一个指针,也就是说服务器中保存着多个数据库(我们可以通过SELECT命令选择要操作的数据库)。我们再观察redisDb数据结构,下面显示出来的三个成员变量指示了数据库的组织结构。首先,redis数据库是键值对(key-value-pair)数据库,dict变量就指示了一个哈希表,用于存储各个键值对对象,之前也提到,key只能为REDIS_STRING,而value可以为不同的对象类型,通过dict变量对这些键值对进行访问;redis数据库有过期删除的机制,而expires变量就是指示各个键空间(key space)的键的过期时间,所以也就是一个字典结构;最后,id指示了当前redisDb的标号,执行SELECT命令时,通过标号进行切换。
struct redisServer {
/* General */
// ...
redisDb *db; // 保存着当前服务器的所有数据库;
// ...
} redisSerevr
typedef struct redisDb {
dict *dict; /* The keyspace for this DB */ // 保存了当前数据库的键空间
dict *expires; /* Timeout of keys with a timeout set */ //键空间中所有键的过期时间
// ...
int id; /* Database ID 从0开始 */
// ...
} redisDb;
其他
- redis的5种数据类型(STRING, LIST, SET, HT, ZSET)的底层实现总结:What are the underlying data structures used for Redis? - Stack Overflow
- 新版本redis增加了stream数据类型;
- 一般情况下,当称呼某一个数据为“XXX键”时,意思指的是这个键值对的值是XXX类型;比如“列表键”代表键值对的值是列表类型;因为键值对的键的类型永远只能是字符串类型;
- 我们都知道有序集合的底层由ziplist或者skiplist实现;当由skiplist实现时,其实底层除了skiplist以外,还包含dict,dict的作用是保存每个字符串value到它的score的映射,因此,redis command
ZSCORE
的时间复杂度为;ZSCORE – Redis
网友评论