Redis的数据结构
redis的数据结构
一、redis的数据结构
1、String字符串类型
Redis的String能够表示字符串、整数、浮点数三种值的类型
应用场景:
- 普通的赋值
- 使用incr、decr命令进行递增和递减统计数据。用于实现乐观锁watch(事物)
- setNx实现分布式锁
底层数据类型:
// 数据结构
struct sdshdr{
//记录buf数组中已使用字节的数量
int len;
//记录 buf 数组中未使用字节的数量
int free;
//字符数组,用于保存字符串
char buf[];
}
- int:当存储为int类型的整数时
- embstr:编码简单的动态字符串。单字符串长度小于44个字节时
- raw:简单的动态字符串,大字符串,当长度大于44个字节时
2、List列表类型
list可用于来存储有序的可重复的数据,可快速获取头尾数据,最多存储2^32-1个元素。
底层数据结构:
1、LinkList:是一个双向链表,双向链表的结构就是包括一个头节点、然后每个节点都有一个头指针指向前一个元素和一个尾指针指向后一个元素。
2、zipList:压缩链表
压缩链表有一个zitail_offset记录了最后一个entry的偏移量,这样就可以快速定位到链表的最后一个元素然后开始倒叙遍历。zipList的entry的数据结构:
typede struct entry{
//前一个entry的长度
int<var> prelen;
//元素类型编码
int<var> encoding;
//元素内容
optional byte[] content;
}
压缩链表和普通LinkList的区别,压缩链表并不是给元素进行压缩,而是链表的空间都是分配连续的而LinkList分配的内存空间是随机分配的这样zipList相比于LinkList就不会出现内存的碎片化。并且由于zipList的空间是连续的所以减少了pre指针和next指针,每个指针需要占用8个字节,少了两个指针就减少了16个字节。
由于zipList是连续的空间,并且没有pre、next指针所以删除新增元素需要元素的拷贝,以及连锁更新操作。所以当元素少的时候list采用zipList存储,元素多的时候采用ListList。
3、quickList
quickList是linkList和zipList的结合,linkList的每一个节点都是一个zipList,当zipList中的元素达到一定的量的时候就会创建linkList另外一个节点的zipList。
应用场景:
- 可以用于实现堆栈
- 可用于阻塞队列
- 可用于各种列表,比如用户列表、商品列表、评论列表等。
参考:Redis底层数据结构之list - 凡尘多遗梦 - 博客园 (cnblogs.com)
3、set集合类型
set集合类型用于保存无序的不重复数据
底层数据结构:
1、intset:当存储的类型为整数并且元素的个数小于set-max-intset-entries的时候使用intset存储数据,intset使用的是一个数组来存储数据。
2、dict字典:当存储的数据不是int类型,或者数据的量超过了set-max-intset-entries则使用字典来存储,字典的key就为数据的值,value等于null。
应用场景:
- 用于保存不能重复且不需要排序的数据,比如关注的用户信息
- 使用spop返回集合中一个随机元素,并将其删除、srandmember返回集合中一个随机元素并不删除。这两个命令来实现随机抽奖功能
4、sortset有序集合类型
存储有序的并且不的数据。sortset中的元素都会关联一个score分数并按照分数排序,分数可重复。
底层数据结构:
1、ziplist:当数据量较少且元素都是小整数或者短字符串时
2、skiplist:跳跃表
应用场景:
- 实现排行榜的功能
5、hash类型
Redis hash 是一个 string 类型的 field 和 value 的映射表,它提供了字段和字段值的映射。
底层数据结构:
1、ziplist:当散列表元素的个数比较少,且元素都是小整数或短字符串时。
2、dict:当散列表元素的个数比较多或元素不是小整数或短字符串时。
应用场景:
- 对象的存储
6、bitmap类型
通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。bitmap的数据主要是key、偏移量offset、值,其中值只能是0和1。极大的节省的内存空间
应用场景:
- 记录员工的打卡记录:key为日期,偏移量是用户id,值为0表示未打卡,1表示已打卡。或者key为用户id,偏移量为日期,值为0表示未打卡,1表示已打卡。
更多推荐
所有评论(0)