redis数据库

136 阅读2分钟

这是我参与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命令,确保是在自己的库中操作。