redis的数据结构
string、list(列表)、hash(哈希)、set(集合)、sorted set(有序集合)、bitmap、geo
键和值用什么结构组织
redis使用一个哈希表来保存所有键值对。
一个哈希表,其实就是一个数组,数组的每个元素称为一个哈希桶。所以,我们常说哈希表是由多个哈希桶组成的,每个哈希桶中保存了键值对数据。
哈希桶中的元素保存的并不是值本身,而是指向具体值得指针。不管值是string,还是集合类型,哈希桶中的元素都是指向他得到的指针。
为什么哈希表操作变慢了?
哈希冲突:两个key的哈希值和哈希桶计算对应关系时,正好落在同一个哈希桶中。
解决哈希冲突的方式,就是链式哈希。链式哈希也很容易理解,就是指同一个hash中的多个元素用一个链表来保存,它们之间一次用指针链接。
Redis的渐进式rehash
集合数据操作效率
和string类型不同,一个集合类型的值,第一步是通过全局哈希表找到对应的哈希桶位置,第二部是在集合中在增删改查。
有哪些底层数据结构
压缩列表
压缩列表实际上类似于一个数组,数组中的每个元素都应保存一个数据,和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltail和zllen,分别表示列表长度,列表尾部的偏移量和列表中的entry个数;压缩列表在表尾还有一个zlend,表示列表结束。
跳表
跳表在链表的基础上,增加了多级索引,通过索引的几个跳转,实现数据的快速定位。
不同操作的复杂度
四字口诀 单元素操作是基础
范围操作非常耗时
统计操作通常高效
例外情况只有几个
第一:单元素操作,是指每一种集合类型对单个数据实现的增删改查操作
第二: 范围操作,是指集合类型中遍历操作,可以返回集合中的所有数据。 比如hash类型的HGETALL和set类型的SMEMBERS,或者返回一个范围内的部分数据,比如list类型的Lrange和zset类型的zrange。这类操作的复杂度一般是o(n)比较耗时,我们应该尽量避免。
不过redis从2.8版本开始提供scan系统操作(比如HSCAN、SSCAN和ZSCAN),这类操作实现了渐进式遍历,每次只返回有限数量的数据。
第三:统计操作,是指集合类型对集合中所有元素个数的记录
第四:例外情况,是指某些数据结构的特殊记录,例如压缩列表和双向链表都会记录表头和表尾的偏移量。