redis学习笔记(15)---redis数据库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012658346/article/details/51366269

创建数据库

  在redis的server端,维护着多个数据库(默认为16个)。
  所有的数据库以数组的形式保存在redisServer结构中

struct redisServer {
    ......
    redisDb *db; //数据库数组
    int dbnum;   //数据库的个数
    ......
 };

  在initServer()初始化server时,会根据dbnum来创建数据库

 server.db = zmalloc(sizeof(redisDb)*server.dbnum);

  dbnum属性值由服务器配置的database选项决定,默认为16。因此redis服务器端默认会创建16个数据库,如下图所示:
  这里写图片描述

切换数据库

  同时每个client也维护着一个redisDB指针,来指向client当前正在操作的数据库
  每次client与server建立连接时,默认的都是选择的0号数据库。
  client可以用命令select来选择具体要操作的数据库。 

typedef struct redisClient {
    ......
    redisDb *db;
    ......
} redisClient;

int selectDb(redisClient *c, int id) {
    if (id < 0 || id >= server.dbnum)
        return REDIS_ERR;
    c->db = &server.db[id];  //指向对应数据库
    return REDIS_OK;
}

  当client执行了命令select 1 之后,如下图所示:
  这里写图片描述

定义

  数据库的定义如下:    

typedef struct redisDb {
    dict *dict;       /* 数据空间,存储所有的key-value对 */
    dict *expires;    /* 记录设置了超时时间的key */
    dict *blocking_keys;  /* 记录被阻塞的key,通常是执行BLPOP等阻塞命令 */
    dict *ready_keys;     /* 可以解除阻塞的键 */
    dict *watched_keys;   /* 正在被 WATCH 命令监视的键 */
    struct evictionPoolEntry *eviction_pool;    /* Eviction pool of keys */
    int id;              /* 数据库ID,从0开始 */
    long long avg_ttl;   /* 用于统计信息 */
} redisDb;

  其中最重要的成员为dict,我们操作的所有数据都保存在dict中,包括字符串、list等所有类型的key-value对。

db->dict

  db->dict由数据结构dict字典实现,用于保存数据库中所有的key-value对。
  数据库中,key和value都是通过对象robject来实现的。其中所有的key都是字符串类型的对象,而value可以是5中类型中的任意一种。
  当执行下列操作后  

set name redis
lpush list 10 20 30
hset hash field val
hset hash website csdn

  得到的数据库示意图如下:
  这里写图片描述
  
  其中键hash对应的value本应是一个ziplist结构,但是为了体现多种编码方式,示意图中以hash表的形式实现。
  

注意

   在db中,通过dict保存所有的key-value对。因此所有的key必须唯一   
   所有的key都是字符串类型的,在找到key对应的value之后,可以通过value指向的对象robject来判断数据的类型。  
   但是对于其它类型的命令,当value与命令类型不一致时,就会报错。   
   这里写图片描述  



本文所引用的源码全部来自Redis3.0.7版本

redis学习参考资料:
Redis 设计与实现(第二版)

猜你喜欢

转载自blog.csdn.net/u012658346/article/details/51366269