这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
Redis的数据库
redis 服务器将所有数据库保持的服务器状态保存在redisServer 的db数组中,db 数组的每个项都是一个redis.h 的redisDB 结构,每个redisDB 结构代表一个数据库。
redis.h 的redisServer
struct redisServer {
/* General */
// 数据库数组
redisDb *db;
int dbnum; /* Total number of configured DBs */
};
在初始化服务器时,程序会根据服务器状态的dbnum属性来决定应该创建多少个数据库,默认16个,但是可以通过database选项来进行配置。
redis目标数据库为0号数据库,可以通过select命令来切换目标数据库。
redisClient结构的db属性记录客户端当前的目标数据库。db属性是一个指向redisDb结构的指针:
/*
* 客户端结构
*
* 为每个连接到服务器的客户端保存维持一个该结构的映射,
* 从而实现多路复用。
*/
typedef struct redisClient {
// socket 文件描述符
int fd;
// 指向当前目标数据库的指针
redisDb *db;
// 当前目标数据库的号码
int dictid;
// 查询缓存
sds querybuf;
size_t querybuf_peak; /* Recent (100ms or more) peak of querybuf size */
// 参数的个数
int argc;
// 字符串表示的命令,以及命令的参数
robj **argv;
// 命令,以及上个命令
struct redisCommand *cmd, *lastcmd;
// 回复类型
int reqtype;
int multibulklen; /* number of multi bulk arguments left to read */
long bulklen; /* length of bulk argument in multi bulk request */
// 保存回复的链表
list *reply;
// 链表中保存的所有回复的总字节大小
unsigned long reply_bytes; /* Tot bytes of objects in reply list */
// 统计数据
int sentlen;
time_t ctime; /* Client creation time */
time_t lastinteraction; /* time of the last interaction, used for timeout */
time_t obuf_soft_limit_reached_time;
int flags; /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */
...
} redisClient;
redisClient 中的db指针指向redisServer 中的db数组中的其中一个元素,被指向的元素就是客户端的目标数据库。
select 命令的原理就是通过修改redisClient 的db指针,让它指向服务器中的不同数据库,从而实现切换目标数据库的功能。
目前没有可以返回客户端目标数据库的命令,在执行redis 命令的时候,我们可能忘记自己操作的是redis 的哪个库,为了避免对数据库进行误操作,最好先执行一下select命令,确保是在自己的库中操作。