Redis_16_Redis服务器中的数据库(键值对的存放和生存时间的存放)

一、前言

Redis是一种基于键值对的非关系型数据库(ps: mongdb也是一种基于键值对的非关系型数据库),有五种基本类型,每一种的都是 key-value 键值对,本文介绍Redis服务端的数据库,说一下这些 key-value 键值对是如何在redis底层存放的。

1、redis的键值对在数据库中如何存放的,如何完成增删查改的。
2、redis的键值对的过期时间/生存时间ttl在数据库中如何存放的。

二、redis服务器中数据库

让我们来见识一下redis中的数据库结构,看一下这些 key-value 是如何在redis底层存放的。

struct redisServer{
       // ...
       //一个数组,保存着服务器中的所有数据库
              redisDb *db;
       //服务器的数据库数量
              int dbnum;
       // ...
};

在这里插入图片描述

对于上述代码和示意图的解释是:Redis服务器将所有数据库都保存在服务器状态redis.h/ redisServer结构的db数组中,db数组的每个项都是一个 redis.h/redisDb结构,每个 redisDb结构(即代码中的redisDb *db)代表一个数据库,同时,程序会根据服务器状态的donum属性(即代码中的int dbnum)来决定应该创建多少个数据库。num属性的值由服务器配置的 database选项决定,默认情况下,该选项的值为16,所以 Redis服务器默认会创建16个数据库:

在这里插入图片描述
在这里插入图片描述

切换数据库:对于redis默认的16个数据库(db0-db15),在操作的时候可以选择将数据(五种类型均可)存放在哪个数据库中,只要将某个数据库设置成当前数据库就好(select 数目),宏观命令如下:

在这里插入图片描述
在这里插入图片描述
底层变化:
在这里插入图片描述

三、从底层原理图讲解redis增删改查操作

Redis是一个键值对(key- value pair)数据库服务器,服务器中的每个数据库都由一个 redis.h/ redisDb结构表示,其中, redisDb结构的dict字典保存了数据库中的所有键值对,我们将这个字典称为键空间( key space):

键空间和用户所见的数据库是直接对应的:

1)键空间的键也就是数据库的键,每个键都是一个字符串对象;

2)键空间的值也就是数据库的值,每个值可以是字符串对象、列表对象、哈希表对象集合对象和有序集合对象中的任意一种Redis对象。

如图:

在这里插入图片描述

对于上图解释:redisDb即表示redis服务器中的数据库,里面有一个dict字典,里面存放数据实体(即key-value键值对),这里有三个key-value键值对,分别是

(key,value)=(“alpha”,“a b c”)为ListObjet类型,

(key,value)=(“book”,“<name,Redis in Action><author,Josiah L.Carlson><publisher,Manning>”)为HashObject类型,

(key,value)=(“alpha”,“hello world”)为StringObject类型

3.1 添加新键

在这里插入图片描述

对于上图解释:添加新键,StringObject类型 <key,value>=<“date”,“2020/02/09”>

3.2 删除键

在这里插入图片描述

对于上图解释:删除新键,删除key为“book”的键值对

3.3 更新键

在这里插入图片描述

对于上图解释:更新键,更新key为“message”的键值对

3.4 对键取值

在这里插入图片描述

对于上图解释:对键取值,获取key为“message”的value

四、生存时间在数据库的存储

Redis每一个键值对都有一个过期时间 ttl,也成为了生存时间,那么,这个时间在redis数据库是如何存放的呢?

4.1 生存时间的设置与读取

介绍四个命令(和TTL time to live 生存时间有关的),用表格清晰些,如下:

命令含义
EXPIRE设置剩余生存时间,以秒为单位,将键key的生存时间设置为ttl秒
PEXPIRE设置剩余生存时间,以毫秒为单位,将键key的生存时间设置为ttl毫秒
EXPIREAT设置剩余生存时间,以秒为单位,将键key的生存时间设置为timestamp所指定的秒数时间戳
PEXPIREAT设置剩余生存时间,以毫秒为单位,将键key的生存时间设置为timestamp所指定的秒数时间戳
TTL返回指定key的剩余生存时间,以秒为单位
PTTL返回指定key的剩余生存时间,以毫秒为单位

这个表格给出了指定key的过期时间的存储,这里需要注意一个点,设置指定key生存时间一共有四个命令EXPIRE PEXPIRE EXPIREAT PEXPIREAT,这里展示四个命令底层关系,如图:

在这里插入图片描述

我们可以看到,四个命令底层关系:四个设置生存时间的命令,底层最终都是使用PEXPIREAT命令去实现的。

4.2 生存时间的底层保存(过期字典)

redis是基于key-value存储的一个非关系型数据库,对于每一个记录的key,都有一个生存时间TTL,上面介绍了指定key的生存时间的读写,那么,redis中每一个key的生存时间是底层是如何存储的呢?答案是使用“过期字典”存储。

过期字典引入:redisDB结构的expires字典保存了数据库中所有键的过期时间,这个expires字典就是过期字典。

过期字典的键:是一个指针,这个指针指向键空间中的某个键对象(也即是某个数据库键)。

过期字典的值:是一个long long类型的整数 ,这个整数保存了键所指向的数据库键的过期时间,即—个毫秒精度的UNIX时间戳。

在这里插入图片描述

展示了一个带有过期字典的数据库例子,在这个例子中,键空间保存了数据库中的所有键值对,而过期时间则保存了数据库中所有按键值对的过期时间。

生存时间(过期时间)的添加和删除略过。

五、尾声

Redis服务端的数据库,完成了。

天天打码,天天进步!