-
Redis数据类型详细讲解(set、hash、zset)
相关资料下载:www.bjpowernode.com/?cnblogs
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):节点的数量。
跳跃表的遍历总是从高层开始,然后随着元素值范围的缩小,慢慢降低到低层。
前面也说了,有序列表是使用skiplist和dict结合实现的,skiplist用来保障有序性和访问查找性能,dict就用来存储元素信息,并且dict的访问时间复杂度为O(1)。
出 处:https://www.cnblogs.com/linkeke/p/15728019.html