redis是一种k-v键值对内存型数据库,redis的键是一个string对象,而值一般包括如下5种对象,即string、list、hash、set、zset。
一般使用TYPE命令查看redis键对应值的对象类型。
对象的底层会使用不同的编码以使用不同的数据结构,一般每种对象至少会使用两种不同的编码。redis的编码类型包括如下的8种,1、REDIS_ENCODING_INT,2、REDIS_ENCODING_EMBSTR,3、REDIS_ENCODING_RAW,4、REDIS_ENCODING_HT,5、REDIS_ENCODING_LINKEDLIST,6、REDIS_ENCODING_ZIPLIST,7、REDIS_ENCODING_INTSET,8、REDIS_ENCODING_SKIPLIST。我们一般使用OBJECT ENCODING命令查看键对应值所使用的编码类型。redis为不同对象提供多种编码,提高了redis的灵活性和效率。
一、String对象
String对象包括如下三种编码,分别是REDIS_ENCODING_INT、REDIS_ENCODING_EMBSTR以及REDIS_ENCODING_RAW。字符串的最大不超过512MB。
如果一个字符串对象保存的是一个整数值,并且这个整数值可以用long类型表示,我们就是用REDIS_ENCODING_INT编码;如果一个字符串的长度小于等于39字节我们使用REDIS_ENCODING_EMBSTR编码,否则则使用REDIS_ENCODING_RAW编码。
注:浮点数使用REDIS_ENCODING_EMBSTR、REDIS_ENCODING_RAW编码,长度超过long类型的整数使用REDIS_ENCODING_EMBSTR、REDIS_ENCODING_RAW编码;对整数进行追加字符串操作的时候,REDIS_ENCODING_INT转成REDIS_ENCODING_RAW,对REDIS_ENCODING_EMBSTR编码的字符串进行追加操作的时候,REDIS_ENCODING_EMBSTR也会转成REDIS_ENCODING_RAW。可以使用APPEND命令验证注释部分。
REDIS_ENCODING_EMBSTR、REDIS_ENCODING_RAW编码内部数据结构在redis中使用的是简单动态字符串(SDS)。SDS使用字节数组保存字符串,并且会记录字符串的长度、字符数组空余的空间。SDS的优势在于1、空间预分配,对SDS进行修改后,如果SDS的长度小于1MB,那么程序分配和len同样大小的未使用空间,反之,程序会分配1MB的未使用空间。2、二进制安全的,SDS不用‘\0’作为字符串结尾的标志,而是使用len的长度来判断,相比于C语言的字符串,是二进制安全的。
二、列表对象
列表对象可以使用REDIS_ENCODING_ZIPLIST、REDIS_ENCODING_LINKEDLIST编码,REDIS_ENCODING_ZIPLIST编码需要满足以下两个条件,1、默认列表对象保存的所有字符串元素的长度都小于64字节;2、列表对象所保存的元素数量小于512个。
三、哈希对象
哈希对象可以使用REDIS_ENCODING_ZIPLIST、REDIS_ENCODING_HT编码,EDIS_ENCODING_ZIPLIST编码需要满足以下两个条件,1、默认列表对象保存的所有字符串元素的长度都小于64字节;2、列表对象所保存的元素数量小于512个。
四、集合对象
集合对象可以使用REDIS_ENCODING_INTSET、REDIS_ENCODING_HT编码,REDIS_ENCODING_INTSET编码需要满足以下两个条件,1、默认列表对象保存的所有的元素都是整数值;2、列表对象所保存的元素数量小于512个。
五、有序集合
有序集合的编码可以使用REDIS_ENCODING_ZIPLIST、REDIS_ENCODING_SKIPLIST编码,EDIS_ENCODING_ZIPLIST编码需要满足以下两个条件,1、默认列表对象保存的所有字符串元素的长度都小于64字节;2、列表对象所保存的元素数量小于128个。
注:有序集合的成员必须唯一,分值可以重复(double类型的浮点数);