Redis 数据库

数据库

本章将对 Redis 数据库的构造和实现进行讨论。

除了说明数据库是如何储存数据对象之外,本章还会讨论键的过期信息是如何保存,而 Redis 又是如何删除过期键的。

数据库的结构

Redis 中的每个数据库,都由一个 redis.h/redisDb 结构表示:

typedef struct redisDb {

    // 保存着数据库以整数表示的号码
    int id;

    // 保存着数据库中的所有键值对数据
    // 这个属性也被称为键空间(key space)
    dict *dict;

    // 保存着键的过期信息
    dict *expires;

    // 实现列表阻塞原语,如 BLPOP
    // 在列表类型一章有详细的讨论
    dict *blocking_keys;
    dict *ready_keys;

    // 用于实现 WATCH 命令
    // 在事务章节有详细的讨论
    dict *watched_keys;

} redisDb;

下文将详细讨论 iddictexpires 三个属性,以及针对这三个属性所执行的数据库操作。

数据库的切换

redisDb 结构的 id 域保存着数据库的号码。

这个号码很容易让人将它和切换数据库的 SELECT 命令联系在一起,但是,实际上,id 属性并不是用来实现 SELECT 命令,而是给 Redis 内部程序使用的。

当 Redis 服务器初始化时,它会创建出 redis.h/REDIS_DEFAULT_DBNUM 个数据库,并将所有数据库保存到 redis.h/redisServer.db 数组中,每个数据库的 id 为从 0REDIS_DEFAULT_DBNUM - 1 的值。

当执行 SELECT number 命令时,程序直接使用 redisServer.db[number] 来切换数据库。

但是,一些内部程序,比如 AOF 程序、复制程序和 RDB 程序,需要知道当前数据库的号码,如果没有 id 域的话,程序就只能在当前使用的数据库的指针,和 redisServer.db 数组中所有数据库的指针进行对比,以此来弄清楚自己正在使用的是那个数据库。

以下伪代码描述了这个对比过程:

def PSEUDO_GET_CURRENT_DB_NUMBER(current_db_pointer):
    i = 0
    for db_pointer in redisServer.db:
        if db_pointer == current_db_pointer:
            break
        i += 1
    return i

有了 id 域的话,程序就可以通过读取 id 域来了解自己正在使用的是哪个数据库,这样就不用对比指针那么麻烦了。

数据库键空间

因为 Redis 是一个键值对数据库(key-value pairs database),所以它的数据库本身也是一个字典(俗称 key space):

redisDb 结构的 dict 属性中,保存着数据库的所有键值对数据。

下图展示了一个包含 numberbookmessage 三个键的数据库 ——其中 number 键是一个列表,列表中包含三个整数值;book 键是一个哈希表,表中包含三个键值对;而 message 键则指向另一个字符串:

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号

返回顶部