Redis是一种非关系型数据库,常用的数据类型主要有五种,分别为String,List,Hash,Set,ZSet,那么他们对应的数据结构分别是什么呢?
字符串
顾名思义,字符串的数据类型最简单,就是使用了String,没有用到复杂的数据结构。
List
列表(List)支持存储一组数据,对应的数据结构有两种,一种是压缩列表(ZipList),一种是双向循环列表。
但是使用压缩列表的时候是有条件的:
- 单个数据小于64字节
- 数据个数小于512
为啥使用两种数据结构呢?使用一种不是更简单,这主要是因为Redis本身是内存数据库,所以就要尽可能的节省内存空间,而压缩列表恰恰能满足这个,压缩列表并不是一种基本的数据结构,而是Redis自己设计的一种数据结构,类似数据,通过连续的内存空间存储数据,但是跟数组不同的一点是它存储的数据大小是不同的,我们知道数据要求每个元素的大小是相同的,如果要存储不同长度的数据,我们就需要最大长度的数据作为元素的大小,当数据小于这个长度时就会浪费部分空间,所以压缩列表便可以起到节省内存的作用。
为啥数据个数要求是512个呢?这是由于因为压缩列表每个数据的长度时不一样的,所以压缩列表在查找数据时并不能按照下标查找的,而是需要遍历进行查找,所以如果数据个数过多,那么申请的内存就会过大,这是我们不想看到的。所以当不满足上面那两个条件时,就需要使用双向链表来存储了。
Hash
Hash又名字典,主要存储键值对,hash也有两种实现方式,一种是压缩列表,一种是散列表。
同样需要满足两个条件时,才会使用压缩列表。
- 键和值的大小都要小于64字节
- 字段的键值对数量要小于512
当不满足上面两个条件时,才会使用散列表。其中Redis使用了MurmurHash2算法作为hash函数,对于hash冲突时,redis使用的事链表法来解决的。
Set
Set主要是用来存储一组不同的数据,这个数据也是有两种实现方式,一种是有序数组,一种是散列表。
使用有序数组是有两个条件:
- 存储的数据都是整数
- 存储的数据元素不超过512
ZSet
有序集合用来存储一组数据,同时每个数据又会附带一个得分,通过得分的大小来对数据进行排序。有序集合也有两种实现方式,一种是压缩列表,一种是跳表。
当满足下面两个条件时,会使用压缩列表:
- 所有数据大小小于64字节
- 元素个数小于128
跳表(skipList) 也是redis设计的一种数据结构,它支持快速的插入,删除、查找操作,可以替代红黑树。跳表的实现主要使用了多级索引,具体的细节可以参考:https://www.jianshu.com/p/43039adeb122
总结
Redis常用的数据类型底层依赖的数据结构,大致有这五种:压缩列表,有序数组,双向链表,散列表,跳表,大致的思路也分析了一下,可能有些偏差还请指教。