redis数据结构

redis有几种数据结构?

  1. 五种基础数据结构先就不多说了,string,list,hash, set, zset
  2. 两种特殊数据结构:位图,HyperLogLog

实现原理及应用场景:

  1. [string] 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。value其实不仅是String,也可以是数字。string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

    应用场景:
    可以利用redis的INCR、INCRBY、DECR、DECRBY等指令来实现原子计数的效果。即可以用来实现业务上的统计计数需求。也可用于实现idmaker,即生成全局唯一的id。 (常规key-value缓存应用。常规计数: 微博数, 粉丝数。)
    实现方式:
    SDS(Simple Dynamic String)简单动态字符串,它是由C语言完成;String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。采用预分配冗余空间方式减少内存的频繁分配。1MB内扩容加倍现有空间,超过1MB每次加1MB。

  2. [list] 是简单的字符串列表,按照插入顺序排序。
    应用场景:
    a.最新消息排行等功能(比如朋友圈的时间线)
    b.消息队列等
    实现方式:
    由链表形成,插入删除操作非常快,时间复杂度O(1);但索引定位很慢,时间复杂度O(n)。实现由压缩列表ziplist 或双向链表linkedlist 因为双向链表占用的内存比压缩列表要多, 所以当创建新的列表键时, 列表会优先考虑使用压缩列表, 并且在有需要的时候, 才从压缩列表实现转换到双向链表实现。 Redis list实现一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

  3. [hash/字典] 是一个键值(key => value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
    应用场景:
    存储部分变更数据,如用户信息等。
    实现方式:
    Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap。存储消耗高于单个string,根据世界情况定吧。

  4. [set]是string类型的无序集合。集合是通过hashtable实现的,概念和数学中个的集合基本类似,可以交集,并集,差集等等,set中的元素是没有顺序的。所以添加,删除,查找的复杂度都是O(1)。
    应用场景:
    set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。 Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用Redis提供的Set数据结构,可以存储一些集合性的数据。可实现如共同关注、共同喜好、共同好友等功能。
    实现方式:
    set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

  5. [zset] 是和 set 一样也是string类型元素的集合,且不允许重复的成员,增加了score.
    应用场景:
    a:如 key 存储学科成绩,value存储学生ID,score存储成绩
    b:如 key 存储城市ID(1101),value存储员工ID,score 存储员工业绩权重分(某相亲网可用)
    实现方式:
    内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。
    (那么为什么要用跳跃表?B+tree不香?)

  6. [位图]严格意义其实并不是一种数据结构,其实就是一种普通的字符串,也可以说是byte数组。
    应用场景:
    假如要统计用户一年签到次数,这里如果用记录表来记录的话,每个用户就用存365条记录,一千个用户就是365*1000条记录,想一下这个数据量是不少的,而且实际业务意义不是很明显。位图就是byte数字,假如签到就表示1,没签到就表示0,这里可以用365个字节来记录前端数,这样很节省资源了,提高效率。用户签到统计,月活跃用户数统计等等业务场景都适合用位图实现
    实现方式:
    我是理解成”位数组“这样吧。

  7. [HyperLogLog]是一种高级数据结构,是用来做基数统计的算法,每个 HyperLogLog 键只需要花费 12 KB 内存,只会根据输入元素来计算基数,而不会储存输入元素本身。
    应用场景:
    如千万UV,允许标准误差0.81%,可用之。
    实现方式:
    暂无😊(实现较复杂,回头再补,该睡觉了。。。),

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页