Redis构建的类型系统
Redis构建了自己的类型系统,主要包括
- redisObject对象
- 基于redisObject对象的类型检查
- 基于redisObject对象的显示多态函数
- 对redisObject进行分配、共享和销毁的机制
C语言不是面向对象语言,这里将redisObject称呼为对象是为了讲述方便,让里面的内容更容易被理解,redisObject其实是一个结构体。
redisObject对象
Redis内部使用一个redisObject对象来表示所有的key和value,每次在Redis数据块中创建一个键值对时,一个是键对象,一个是值对象,而Redis中的每个对象都是由redisObject结构来表示。
在Redis中,键总是一个字符串对象,而值可以是字符串、列表、集合等对象,所以我们通常说键为字符串键,表示这个键对应的值为字符串对象,我们说一个键为集合键时,表示这个键对应的值为集合对象
redisobject最主要的信息:
redisobject源码typedef struct redisObject{ //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层数据结构的指针 void *ptr; //引用计数 int refcount; //记录最后一次被程序访问的时间 unsigned lru:22;}robj
- type代表一个value对象具体是何种数据类型type key :判断对象的数据类型
- encoding属性和*prt指针prt指针指向对象底层的数据结构,而数据结构由encoding属性来决定
![933e8d2fbe93d8a1d958e6bb0bb24e04.png](https://i-blog.csdnimg.cn/blog_migrate/455f889c066a250cd6b85e242cbbd3df.jpeg)
- 每种类型的对象至少使用了两种不同的编码,而这些编码对用户是完全透明的。
![e6b832bdd428d3b9282f1b2e9b956a9c.png](https://i-blog.csdnimg.cn/blog_migrate/57735456303db7ce97f4f95ecc23ae48.jpeg)
- object encoding key命令可以查看值对象的编码
命令的类型检查和多态
Redis命令分类
- 一种是只能用于对应数据类型的命令,例如LPUSH和LLEN只能用于列表键, SADD 和 SRANDMEMBER只能用于集合键。
- 另一种是可以用于任何类型键的命令。比如TTL。
当执行一个处理数据类型的命令时,Redis执行以下步骤:
- 根据给定 key ,在数据库字典中查找和它相对应的 redisObject ,如果没找到,就返回 NULL 。
- 检查 redisObject 的 type 属性和执行命令所需的类型是否相符,如果不相符,返回类型错误。
- 根据 redisObject 的 encoding 属性所指定的编码,选择合适的操作函数来处理底层的数据结构。
- 返回数据结构的操作结果作为命令的返回值。
5种数据类型对应的编码和数据结构
string
string 是最常用的一种数据类型,普通的key/value存储都可以归结为string类型,value不仅是string,也可以是数字。其他几种数据类型的构成元素也都是字符串,注意Redis规定字符串的长度不能超过512M
- 编码 字符串对象的编码可以是int raw embstr
- int编码:保存的是可以用long类型表示的整数值
- raw编码:保存长度大于44字节的字符串
- embstr编码:保存长度小于44字节的字符串
int用来保存整数值,raw用来保存长字符串,embstr用来保存短字符串。embstr编码是用来专门保存短字符串的一种优化编码。
Redis中对于浮点型也是作为字符串保存的,在需要时再将其转换成浮点数类型
- 编码的转换
- 当 int 编码保存的值不再是整数,或大小超过了long的范围时,自动转化为raw
- 对于 embstr 编码,由于 Redis 没有对其编写任何的修改程序(embstr 是只读的),在对embstr对象进行修改时,都会先转化为raw再进行修改,因此,只要是修改embstr对象,修改后的对象一定是raw的,无论是否达到了44个字节。
- set/get
- set:设置key对应的值为string类型的value (多次set name会覆盖)
- get:获取key对应的值
- mset /mget
- mset