欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Redis(源码剖析):16---数据库之服务器中的数据库(struct redisDb)

程序员文章站 2022-05-20 15:25:34
...

一、服务器中的数据库

  • Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,db数组的每个项都是一个redis.h/redisDb结构,每个redisDb结构代表一个数据库:
struct redisServer {
    // ...
    redisDb *db; // 一个数组,保存着服务器中的所有数据库
    // ...
};

数据库数量(dbnum)

  • 数据库的数量:在初始化服务器时,程序会根据服务器状态的dbnum属性来决定应该创建多少个数据库:
struct redisServer {
    // ...
    int dbnum;//服务器的数据库数量
    // ...
};
  • dbnum属性的值由服务器配置的database选项决定,默认情况下,该选项的值为16,所 以Redis服务器默认会创建16个数据库,如下图所示:

Redis(源码剖析):16---数据库之服务器中的数据库(struct redisDb)

二、数据库的切换(SELECT)

  • 每个Redis客户端都有自己的目标数据库,每当客户端执行数据库写命令或者数据库读命 令的时候,目标数据库就会成为这些命令的操作对象
  • 默认情况下,Redis客户端的目标数据库为0号数据库,但客户端可以通过执行SELECT命令来切换目标数据库
  • 以下代码示例演示了客户端在0号数据库设置并读取键msg,之后切换到2号数据库并执行类似操作的过程:

Redis(源码剖析):16---数据库之服务器中的数据库(struct redisDb)

  • 在服务器内部,客户端状态redisClient结构的db属性记录了客户端当前的目标数据库,这个属性是一个指向redisDb结构的指针:
typedef struct redisClient {
    // ...
    redisDb *db;//记录客户端当前正在使用的数据库
    // ...
} redisClient;
  • redisClient.db指针指向redisServer.db数组的其中一个元素,而被指向的元素就是客户端 的目标数据库

演示案例

  • 比如说,如果某个客户端的目标数据库为1号数据库,那么这个客户端所对应的客户端 状态和服务器状态之间的关系如下图所示

Redis(源码剖析):16---数据库之服务器中的数据库(struct redisDb)

  • 如果这时客户端执行命令SELECT 2,将目标数据库改为2号数据库,那么客户端状态和 服务器状态之间的关系将更新成下图所示

Redis(源码剖析):16---数据库之服务器中的数据库(struct redisDb)

  • 通过修改redisClient.db指针,让它指向服务器中的不同数据库,从而实现切换目标数据 库的功能——这就是SELECT命令的实现原理

Redis(源码剖析):16---数据库之服务器中的数据库(struct redisDb)