一、Redis基础数据结构简介

本文只是博主自己学习的一个记录,不会对使用命令有过多的描述。

String(字符串)

      字符串string是Redis最简单的数据结构,他的内部表示和Java一样就是一个字符数组。Redis所有的数据结构都以唯一的key字符串作为名称,然后通过这个唯一key值来获取相应的value数据。不同类型的数据结构的差异就在于value的结构不一样。
      字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体使用JSON序列化成字符串,然后将序列化后的字符串塞进Redis来缓存。同样,取用户信息会经过一次反序列化的过程。
      Redis的字符串是动态字符串,是可以修改的字符串,内部结构的实现类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,一般来说当前字符串分配的实际空间capacity要高于实际字符串长度len。**当字符串长度小于1MB时,扩容都是倍数增加。如果字符串长度超过1MB,扩容时一次只会多扩1MB的空间。字符串的最大长度为512MB。 **

操作示例

set key value : 设置一个k,v
setex key expire value:设置一个key,存活时间为expire
setnex key value: 设置一个key,不存在添加,存在不添加
exists key : 是否存在该key
del key: 删除一个key
mset key1 val1 key2 val2 : 设置多个k,v
mget key1 key2 : 获取多个k,v
incr key :value为数字时自增1
incrby key num : value为数字时自增指定num大小

  • 键值对
    相当于字典的key和value,支持简单的增删改查操作。
    在这里插入图片描述
  • 批量键值对
    可以对多个字符串进行批量读写, 节省网络耗时。
    在这里插入图片描述
  • 过期和set命令扩展
    可以对key设置过期时间,到时间后会被自动删除。用expire命令对key进行过期时间设置,也可以直接使用setex命令。
    setnx命令在key不存在时才会创建成功,key存在创建就会失败。
    在这里插入图片描述
  • 计数
    如果value是一个整数,还可以对他进行自增操作。自增是有范围的,他的范围在有服号long的最大值和最小值之间,超出这个范围,redis会直接报错。
    在这里插入图片描述

List(列表)

      Redis的列表相当于Java里面的LinkedList, 是一个双向链表。所以他的插入和删除操作非常快,时间复杂度为O(1),但是索引定位很慢,时间复杂度为O(n),详细原理就不多说了,对链表很了解的都知道了。。。
      Redis的列表结构也可以作为异步队列使用,将需要异步处理的数据序列化成字符串塞进列表中,另一个线程从列表中轮询获取数据进行相应的梳理。当然这个队列肯定不如常用的MQ中间件稳定,使用要看场景。。。
      其实细了解Redis的列表,他的底层数据结构并不是一个简单的LinkedList,而是一个快速链表(QuickList)的结构。列表元素少的时候会使用一块连续的内存存储,这个结构是zipList,也就是压缩链表。它将所有的元素分配一块连续的内存,有点类似数组,当数据量多的时候才会变成QuickList。以为只要是链表就会附带指针的空间,会存在空间浪费,也会造成大量的内存碎片。所以Redis将链表和zpilist结合组成了QuickList,多个ziplist之间采用双向指针相连。这里只是简介,后续再深入分析。。。

操作示例

rpush、lpush key val1 val2 val3 : 添加元素 添加方向相反
rpop、lpop key : 弹出元素 弹出方向相反
llen key : 获取链表长度
lrange key startindex endindex : 参数为两个下标,获取该下标范围内的所有元素

  • 当做队列(入队和出队方向相反)
    在这里插入图片描述
  • 当做栈(入队和出队方向相同)
    在这里插入图片描述
  • 列表的慢操作(慎用)
    既然是一个双向链表,肯定就存在着一些慢操作,也就是时间复杂度高的操作。
    lindex命令相当于Java链表的get(int index)方法,这是一个O(n)的操作,index却大性能越差。
    ltrim命令要传递两个参数作为链表中元素的下标,这个区间内的元素会保留,区间之外的元素全部删除。注意这同样是一个O(n)的操作。
    这里面的index参数和python一样可以传递负数,负号代表倒数。
    在这里插入图片描述

Hash(字典)

      Redis的字典相当于Java里面的HashMap,没有顺序且key唯一,都是数组+链表的结构。当发生hash碰撞的时候采用链表解决。不同的是Redis的字典只能存储字符串,并且他们rehash的方式不同,Java中的HashMap在发生扩容的时候会对所有的元素做一次rehash。而Redis采用的是渐进式rehash。
      简单说一下渐进式rehash,这种rehash的方式会在执行的过程中同时保存新旧两个hash结构,查询元素的时候会同时查询两个hash表,将旧hash表中的元素一点点迁移到新的hash结构中。同样,当旧的hash表中没有元素时,该数据结构会被自动删除并释放内存。
      同字符串一样,hash结构中的单个子key也可以进行技术,它对应的指令是hincrby, 和incr的使用一样。

使用示例

hset key value : 添加一个对k,v
hgetall key : 获取所有k,v
hmset k1 v1 k2 v2 : 添加多对k,v
hincrby key num : 当key对应的value是数字的时候自增num

在这里插入图片描述

Set(集合)

      Redis的集合相当于Java里面的HashSet,同样无序且元素唯一,是一个特殊的字典,字典中的所有value全是NULL。他的key是不可以重复的,所以有去重功能。同样当集合中没有元素时,数据结构会被自动删除并回收内存。

使用示例

sadd key value : 添加元素
smembers key : 获取所有元素
sismember key value : 判断是否存在某个元素
scard key : 查看集合元素个数
spop key 弹出一个元素

在这里插入图片描述

ZSet(有序列表)

      ZSet是Redis最具特色的数据结构,有点类似于Java的SortedSet和HashMap的结合体,一方面它是一个set,保证的value的唯一性,另一方面它给每个value赋值了一个score,作为这个value的排序权重。他内部的数据结构是一个"跳表”,这里不对跳表做过多描述,后面单开一章描述跳表。ZSet同样也是元素被全部删除后自动删除数据结构并回收内存。

使用示例

zadd key score value : 添加一个元素并指定score
zrange key startindex endindex : 获取参数区间内的元素,按score排序输出
zrevrange key startindex endindex : 获取参数区间内的元素,按score逆序输出
zcard key : 获取元素数量
zscore key value : 获取指定value的score
zrank key value : 获取指定value的排名
zrangebyscore key startscore endscore :获取指定score区间内的元素
zrem key value :删除对应value

在这里插入图片描述

总结

  • list、set、hash、zset这四种数据结构是容器型数据结构,他们共享以下两条规则。
    (1) create if not exists : 如果容器不存在,先创建再进行操作。
    (2) drop if no elements :如果容器中没有元素,那么立即删除容器并释放内存。

  • Redis所有数据结构都可以设置过期时间,但是要注意,过期时间是以对象为单位的,例如一个hash结构的过期是整个hash对象的过期,而不是某个子key。并且如果一个字符串已经设置了过期时间,然后又调用了set命令修改了该字符串,那么过期时间就会消失。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值