Redis数据类型及编码

Redis数据类型及编码

说到Redis的数据类型,我们大概会很快想到Redis的5种常见的数据类型:字符串(String)、列表(List)、散列(Hash)、集合(Set)、有序集合(Sorted Set),以及他们的特点和运用场景及常用命令。不过在讲五大数据类型之前,我们有必要看一下redis中的全局操作命令,下面列出了一些常用的操作及其时间复杂度和使用场景。

在这里插入图片描述

全局命令中大多都是针对key的属性设置和修改,除了全局操作以外,redis的五个常用数据类型也有自己的单独对的操作命令,我们下面就来一个个看一下,顺便把这些数据类型的内部原理也大概了解一下。

在这里插入图片描述

要讲内部原理,首先我们得看看redis中有多少种编码方式:

/* Objects encoding. Some kind of objects like Strings and Hashes can be
 * internally represented in multiple ways. The 'encoding' field of the object
 * is set to one of this fields for this object. */
#define OBJ_ENCODING_RAW 0     /* Raw representation */
#define OBJ_ENCODING_INT 1     /* Encoded as integer */
#define OBJ_ENCODING_HT 2      /* Encoded as hashtable */
#define OBJ_ENCODING_ZIPMAP 3  /* Encoded as zipmap */ // 已废弃
#define OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6  /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */

不懂这些编码方式不要紧,后面都会讲到。下面我们就从五个数据类型出发,依次讲解。

(一)String 字符串

string是redis最基本的数据类型,一个key对应一个value。string类型是二进制安全的,意思是redis的string可以包含任何数据,比如图片或者序列化的对象 等等。string类型是redis最基本的数据类型,一个键最大能存储512MB的数据。String 数据结构是简单的 key-value 类型。

string类型一共有三种编码方式,分别是int,raw, embstr。

1.int编码

字符串对象保存的值是一个整数值,并且这个整数值在 long 的范围内,那么 redis 用整数值来保存这个信息,字符串编码设置为int。

2.raw编码

字符串对象保存的是一个字符串,长度大于 32 个字节,就会使用SDS(简单动态字符串)数据结构来保存这个字符串值,并且将字符串对象的编码设置为raw。

3.embstr编码

字符串对象保存的是一个字符串,长度小于 32 个字节,会使用embstr来保存,embstr编码是对SDS的一个优化,采用连续的空间保存,即将SDS的值和字符串对象的值放在一块连续的内存空间上。主要用于为使用较小的字符串对象时提高效率。另外,embstr编码是只读的,只要发生修改操作,就会将编码转换成raw再进行操作。

PS:若字符串保存的为浮点数,那么浮点数将先被转化为字符串,再根据上面的三种情况来选择编码方式。浮点数在进行操作时时,需要从字符串转换成浮点数进行计算,然后再转换成字符串进行保存。

在这里插入图片描述

(二)Hash 哈希

hash类型很像一个关系型数据库的数据表,hash的Key是一个唯一值,Value部分是一个 hashmap的结构。hash数据类型在存储对象时具有比 string 类型更灵活、更快的优势,具体的说,使用 string 类型存储,必然需要转换和解析 json 格式的字符串,即便不需要转换,在内存开销方面,还是 hash 更占优势。hash的模型基本上是这样:

在这里插入图片描述
哈希对象的编码有ziplist和hashtable。

1.ziplist编码

键值对的键和值的长度都小于 64 字节,且键值对个数小于 512时,使用ziplist编码,底层数据结构使用ziplist,用两个连续的ziplist节点来表示哈希对象中的一个键值对。

2.hashtable编码

键值对的键或值的长度大于 64 字节,或键值对个数大于512时使用hashtable编码,底层数据结构使用hashtable。哈希在结构上和hashtable非常相似,因此哈希对象中的每一个键值对都是hashtable中的一个键值对。

在这里插入图片描述

(三)List 列表

redis中的列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),就像一个双向队列。

在这里插入图片描述

list类型经常会被用于消息队列的服务,以完成多程序之间的消息交换。在较老版本中(好像是3.2以下),list一共使用了两种数据结构:压缩链表和双向链表。当元素数量较少的时候,使用压缩列表,当元素数量增多,就使用双向链表。

但是在3.2之后,一个新的数据结构——快速列表(quicklist)出现了,这个数据结构现在已经成为了所有列表的底层实现。

在这里插入图片描述

(四)Set 集合

set 就是一个集合,集合的概念就是一堆不重复值的组合。利用redis提供的set数据类型,可以存储一些集合性的数据。redis的set是string类型的无序集合。集合最大的优势在于可以进行交集并集差集操作。Set可包含的最大元素数量是4294967295。

在这里插入图片描述
集合对象的编码有intset和hashtable。

1.intset编码

集合中的所有元素都是整数,且数量不大于 512 个的时候,使用 intset 编码。intset 编码底层使用intset数据结构。

2.hashtable编码

元素不符合全部为整数值且元素个数小于 512时,集合对象使用的编码方式为 hashtable。hashtable的每一个键都是一个字符串对象,其中保存了集合里的一个元素,hashtable的值全部被设置为NULL。

在这里插入图片描述

(五)Sorted Set 有序集合

和set相比,sorted set是将set中的元素增加了一个权重参数score,使得集合中的元素能够按 score进行有序排列。sorted set 和set一样也是string类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。set的成员是唯一的,但分数(score)却可以重复。sorted set是插入有序的,即自动排序。

有序集合对象的编码有ziplist和skiplist。

1.ziplist编码

当元素数量少于128且所有元素成员的长度小于64字节时使用ziplist编码,有序集合对象的实现数据结构为ziplist, 每个集合的元素 (key-value), 使用两个紧挨着的ziplist的节点来表示,第一个节点保存集合元素的成员 (member), 第二个节点保存集合元素的分数(score)。在压缩列表的内部,集合元素按照分值从小到大进行排序。

2.skiplist编码

当元素数量大于128且所有元素成员的长度大于64字节时使用skiplist编码,内部使用zset来实现数据的保存。

在这里插入图片描述

最后,我们总结一下五种数据类型和所用的编码:

在这里插入图片描述
2020年4月28日

猜你喜欢

转载自blog.csdn.net/weixin_43907422/article/details/105728058
今日推荐