面试官:有一种数据类型,Redis 要存两次,为什么?( 三 )


为什么同时选择使用字典和跳跃表
有序集合直接使用跳跃表或者单独使用字典完全可以独自实现,但是我们想一下,如果单独使用跳跃表来实现,那么虽然可以使用跨度大的指针去遍历元素来找到我们需要的数据,但是其复杂度仍然达到了 O(logN),而字典中获取一个元素的复杂度是 O(1),而如果单独使用字典虽然获取元素很快,但是字典是无序的,所以如果要范围查找就需要对其进行排序,这又是一个耗时的操作,所以 Redis 综合了两种数据结构来最大程度的提升性能,这也是 Redis 设计的精妙之处 。
编码
压缩列表在列表对象和哈希对象都有使用到,想详细了解的可以点击这里 。
和编码转换
当有序集合对象同时满足以下两个条件时,会使用编码进行存储:
有序集合对象常用命令
了解了操作有序集合对象的常用命令,我们就可以来验证下前面提到的哈希对象的类型和编码了,在测试之前为了防止其他 key 值的干扰,我们先执行命令清空 Redis 数据库 。
在执行命令之前,我们先把配置文件中的参数zset-max--修改为 2,然后重启 Redis 服务 。
重启完成之后依次执行如下命令:
zadd name 1 zs 2 lisi //设置 2 个元素会使用 ziplisttype name //查看类型object encoding name //查看编码zadd address 1 beijing 2 shanghai 3 guangzhou 4 shenzhen//设置4个元素则会使用 skiplist编码type address//查看类型object encoding address //查看编码
得到如下效果:
总结
【面试官:有一种数据类型,Redis 要存两次,为什么?】本文主要分析了集合对象和有序集合对象的底层存储结构和的实现原理,并且重点分析了有序集合如何实现排序以及为何同时使用两种数据结构(字典和跳表)同时进行进行存储数据的原因 。