您的位置:首页 > 数据库 > Redis

Redis 对象

2016-06-22 09:55 507 查看
    
 Redis并没有直接使用这些基础数据结构实现键值对的数据库,而是基于这些数据结构创建一个对象系统。包括字符串对象,列表对象,哈希对象,集合对象和有序集合对象。

     Redis中每个对象都由一个redisObject结构表示,该结构如下:

typedef struct redisObject {
     unsigned type:4;//类型,记录了对象的类型, 这个类型包括下面表格8-1
     unsigned encoding:4;//编码
     void *ptr; //指向底层实现数据结构的指针
     int refcount; //对象的引用计数
     unsigned leu:22;//对象最后一次被命令程序访问的时间

}robj;



对一个数据库键执行 TYPE 命令可以来查看键对应值的类型,对应的列表如下:

编码决定了使用什么样的底层数据结构,下图对应的编码:

用OBJECT ENCODING命令查看数据库值对象的编码。

1.字符串对象

编码可以是int,raw和enbstr
当字符串保存的是整数值,例如: SET number 10086 那么对象结构如下:



如果是大于32个字节的字符串,SET story “Long, long ago there lived a king …” , 对象的类型是raw, 对象结构如下:


如果字符串长度小于32字节,字符串对象将使用embstr编码方式保存,他是专门用于保存短字符串的一种优化编码方式。embstr仅会调用一次内存分配函数来分配连续内存空间。raw是两次。因此在释放空间的时候也只需一次。
     用long double类型表示的浮点数在Redis中也是作为字符串保存的。程序会现将这个浮点数转换成字符串值。字符串值保存各种不同对象值所用的编码:

embstr编码的字符串对象是制度的,对embstr字符串对象执行的修改命令程序会先转化成raw类型,然后执行修改。

2.列表对象

编码可以是zippiest或linked list,zippiest是压缩的对于 RPUSH number 1 “three” 5,  ziplist的存储格式如下:

对于linked list编码的使用双端队列底层实现,每个节点保存了一个字符串对象,其结构如下所示:

当满足下面条件时列表对象使用ziplist编码(1).列表对象保存的所有字符串长度小于64字节.(2).列表对象保存的元素数量小于512个



3.哈希对象
哈希对象的编码可以是zippiest或者hashtable, ziplist使用压缩列表实现,对于ziplist实现举个例子:
HSET profile name “Tom"
HSET profile age 25
HSET profile career “Programmer"
使用了ziplist的哈希对象如下:

使用了hashtable编码的结构如下:


当同时满足下面两个条件时使用ziplist编码格式存储哈希对象:(1).哈希对象保存的所有键值对的键和值的字符串长度都小于64字节。(2).哈希对象保存的键值对数量小于512个。



4.集合对象

集合对象的编码可以是:intset或者hash table. intset编码的对象使用的是整数集合作为底层实现。


当集合对象同时满足下面两个条件时,对象使用intset编码:(1).集合对象保存的都是整数值。(2).集合对象保存的元素不超过512个。



5.有序集合对象

可以使用ziplist或者skiplist编码。使用ziplist的时候每个几何元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素 成员,第二个节点保存分数。并且压缩列表集合元素是从小到大排序的。

ZADD price 8.5 apple 5.0 banana 6.0 cherry

              

如果是skiplist编码的有序集合对象,使用zset结构作为底层实现:
typedef struct set {
     zskiplist *zsl; //
     dict *dict;//保存成员到分值的映射

}zset;

对于使用zset结构的存储结构图如下:



当同时满足下面两个条件时,对象使用ziplist编码:(1).有序集合保存元素数量小于128.(2).有序集合保存的所有元素成员长度小于64字节


6.类型检查与命令多态

有些命令可以适用于任意类型。例如: DEL, EXPIRE, RENAME, TYPE, OBJECT, 有些只适用于指定类型:

SET, GET, APPEND, STRLEN等适用于字符串键执行
HDEL, HSET, HGET, HLEN等适用于哈希键执行
RPUSH, LPOP, LINSERT, LLEN等适用于列表键
SADD, SPOP, SINTER, SCARD等适用于集合键
ZADD, ZCARD, ZRANK, ZSCORE等适用于有序集合键

在执行Redis命令之前会先检查对象是否支持对应的命令,命令检查是通过redisObject中的type实现的。


7.对象的共享
通过引用计数来实现,类似于智能指针,这样可以节省空间

8.对象的空转时长
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Redis