金鞍玉勒寻芳客,未信我庐别有春。这篇文章主要讲述Redis数据类型详细讲解(sethashzset)相关的知识,希望能为你提供帮助。
Redis的基本数据类型-2
相关视频参考(来自动力节点):https://www.bilibili.com/video/BV1Uz4y1X72A
相关资料下载:http://www.bjpowernode.com/?csdn
1)set (集合)redis的集合和列表都可以存储多个字符串,它们之间的不同在于,列表可以存储多个相同的字符串,而集合则通过使用散列表(hashtable)来保证自已存储的每个字符串都是各不相同的(这些散列表只有键,但没有与键相关联的值),redis中的集合是无序的。还可能存在另一种集合,那就是intset,它是用于存储整数的有序集合,里面存放同一类型的整数。共有三种整数:int16_t、int32_t、int64_t。查找的时间复杂度为O(logN),但是插入的时候,有可能会涉及到升级(比如:原来是int16_t的集合,当插入int32_t的整数的时候就会为每个元素升级为int32_t)这时候会对内存重新分配,所以此时的时间复杂度就是O(N)级别的了。注意:intset只支持升级不支持降级操作。
intset在redis.conf中也有一个配置参数set-max-intset-entries默认值为512。表示如果entry的个数小于此值,则可以编码成REDIS_ENCODING_INTSET类型存储,节约内存。否则采用dict的形式存储。
2)hash (哈希)hash底层的数据结构实现有两种:
一种是ziplist,上面已经提到过。当存储的数据超过配置的阀值时就是转用hashtable的结构。这种转换比较消耗性能,所以应该尽量避免这种转换操作。同时满足以下两个条件时才会使用这种结构:
当键的个数小于hash-max-ziplist-entries(默认512)
当所有值都小于hash-max-ziplist-value(默认64)
另一种就是hashtable。这种结构的时间复杂度为O(1),但是会消耗比较多的内存空间。
3)zset (有序集合)有序集合和散列一样,都用于存储键值对:有序集合的键被称为成员(member),每个成员都是各不相同的。有序集合的值则被称为分值(score),分值必须为浮点数。有序集合是redis里面唯一一个既可以根据成员访问元素(这一点和散列一样),又可以根据分值以及分值的排列顺序访问元素的结构。
它的存储方式也有两种:
是ziplist结构。
与上面的hash中的ziplist类似,member和score顺序存放并按score的顺序排列
另一种是skiplist与dict的结合。
skiplist是一种跳跃表结构,用于有序集合中快速查找,大多数情况下它的效率与平衡树差不多,但比平衡树实现简单。redis的作者对普通的跳跃表进行了修改,包括添加span\\tail\\backward指针、score的值可重复这些设计,从而实现排序功能和反向遍历的功能。
一般跳跃表的实现,主要包含以下几个部分:
- 表头(head):指向头节点
- 表尾(tail):指向尾节点
- 节点(node):实际保存的元素节点,每个节点可以有多层,层数是在创建此节点的时候随机生成的一个数值,而且每一层都是一个指向后面某个节点的指针。
- 层(level):目前表内节点的最大层数
- 长度(length):节点的数量。
【Redis数据类型详细讲解(sethashzset)】 前面也说了,有序列表是使用skiplist和dict结合实现的,skiplist用来保障有序性和访问查找性能,dict就用来存储元素信息,并且dict的访问时间复杂度为O(1)。
推荐阅读
- 算法 | 第3章 栈与队列相关《程序员面试金典》#yyds干货盘点#
- Shell脚本基本编辑规范及变量
- #yyds干货盘点#十大经典排序之(基数排序 |计数排序)
- 流水线pipeline招式之声明式(前篇)
- go -Unmarshal 错误的几种情况
- #yyds干货盘点#ECMAScript 6 - Symbol
- vue日期转换及时区问题 #yyds干货盘点#
- 未捕获的TypeError(无法读取未定义的属性”id”)
- 未捕获的ArgumentCountError(函数wc_get_page_id()的参数太少)