03_五大常用类型操作

哪五大常用类型?

  1. 字符串(String)
  2. 列表(List)
  3. 集合(Set)
  4. 哈希表(Hash)
  5. 有序集合(SortedSet)

五大常用类型介绍

1. String(字符串)

  • String 是 Redis最基本的类型,它是二进制安全的。
    • 二进制安全:意味着Redis可以包含任何数据。例如:JPG图片或者其他序列化的对象。
  • 一个字符串值最多可以是512M。

在这里插入图片描述

  • 字符串的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配
  • 如图所示,内部为当前字符串实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间;如果超过1M,扩容时一次只会多扩1M的空间。

2. List(列表)

  • 列表是单键多值的结构。
  • Redis列表是最简单的字符串列表,按照插入顺序排列。
  • 我们可以从列表的头部(左边)或者尾部(右边)添加元素到列表中。
  • 列表的底层实际是个双向链表,对两端的操作性能高,通过索引下标操作中间的节点性能会较差。

在这里插入图片描述

列表的数据结构为快速链表(quicklist)。

在这里插入图片描述

  • 首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist(压缩列表)。
    • ziplist将所有的元素紧挨着一起存储,分配的是一块连续的内存。
  • 当列表存储的数据量比较多的时候才会形成quicklist结构。Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
    • 普通的链表需要的附加指针空间太大,会比较浪费空间。例如:这个列表里存的只是int类型的数据,结构上还需要两个额外的指针prev和next。

3. Set(集合)

  • Redis Set对外提供的功能与List类似,是一个列表的功能,特殊之处在于Set是可以==自动排重(排除重复数据)==的。当我们需要存储一个列表数据,又不希望出现重复数据时,它是一个很好的选择。
  • Set提供了判断某个成员是否在一个Set集合内得重要接口,这也是List所不能提供的。
  • Set是String类型的无序集合它底层其实是一个value为null的hash表,所有添加、删除、查找的复杂度都是O(1)
    • 一个算法,随着数据的增加,执行事件的长短,如果是O(1),数据增加,查找数据的事时间不变。
  • Set数据结构是dict字典,字典是用哈希表实现的。
    • Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。
    • Redis的Set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值。

4. Hash(哈希表)

  • Hash表是一个键值对集合。它是一个String类型的field 和 value 的映射表,hash特别适合用于存储对象。类似于Java里面的Map<String, Object>。

用户ID为查找的key,存储的value用户对象包括姓名、年龄、生日等信息,如果用普通的key/value结构来存储。以下有3种存储方式

方式一:

在这里插入图片描述

每次修改用户的某个属性需要,先反序列化改好后再序列化回去。开销较大。

方式二:

在这里插入图片描述

用户ID数据冗余。

方式三:

在这里插入图片描述

通过==key(用户ID)+ field(属性标签)==就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。

Hash类型对应的数据结构有两种:ziplist(压缩列表)hashtable(哈希表)

当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。

5. SortedSet(有序集合)

  • Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
  • 不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了。
  • 因为元素是有序的,所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。
  • 访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。

​ SorteSet(zset)是Redis提供的一个非常特别的数据结构,一方面它等价于Java的数据结构Map<string, Double>,可以给每一个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。

zset底层使用了两个数据结构

  1. hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
  2. 跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。

5.1 跳跃表

有序集合在生活中比较常见,例如根据成绩对学生排名,根据得分对玩家排名等。对于有序集合的底层实现,可以用数组、平衡树、链表等。

但是它们有如下的缺点:

  • 数组不便元素的插入、删除。

  • 平衡树或红黑树虽然效率高但结构复杂。

  • 链表查询需要遍历所有效率低。

Redis采用的是跳跃表。跳跃表效率堪比红黑树,实现远比红黑树简单。

对比有序链表和跳跃表,从链表中查询出51

  1. 有序链表

在这里插入图片描述

要查找值为51的元素,需要从第一个依次查找,比较才能找到。共需要6次比较。

  1. 跳跃表

在这里插入图片描述

从第2层开始,1节点比51节点小,向后比较。

21节点比51节点小,继续向后比较,后面就是NULL了,所以从21节点向下到第1层。

在第1层,41节点比51节点小,继续向后,61节点比51节点大,所以从41向下

在第0层,51节点为要查找的节点,节点被找到,共查找4次。

从此可以看出跳跃表比有序链表效率高。

常用操作命令

1. String(字符串)

1.1 设置值

命令:SET key value [EX seconds] [PX milliseconds] [NX|XX]

在这里插入图片描述

  • EX second :设置键的过期时间为 second 秒。
  • PX millisecond :设置键的过期时间为 millisecond 毫秒。
  • NX :只在键不存在时,才对键进行设置操作。
  • XX :只在键已经存在时,才对键进行设置操作。

1.2 查询值

命令:get key

在这里插入图片描述

注:若获取到字符串,则返回字符串值,否则返回nil(特殊值)。

1.3 追加指定字符串到原字符串末尾

命令:append key value

在这里插入图片描述

注:若原字符串不存在,则为新建设置值

1.4 获取字符串值长度

命令:strlen key

在这里插入图片描述

1.5 设置值(当设置的key原来不存在时)

命令:setnx key value

在这里插入图片描述

注:将key的值设为value,当且仅当key不存在。若给定的key已经存在,则该命令不做任何动作。

1.6 自增(加 1)

命令:incr key

在这里插入图片描述

注:如果key不存在,那么key的值会先被初始化为0,然后再执行INCR操作。本操作的值限制在64位有符号数字表示之内。

1.7 自减(减 1)

命令:decr key

在这里插入图片描述

注:限制条件等同于自增。

1.8 指定步长自增或自减

命令:incrby / decrby key 步长

在这里插入图片描述

1.9 同时设置多个值

命令:mset key1 value1 key2 value2 …

在这里插入图片描述

注:有一个值失败了,则都会失败。

1.10 同时获取多个值

命令:mget key1 key2 …

在这里插入图片描述

1.11 key不存在时,同时设置多个值

命令:msetnx key1 value1 key2 value2 …

在这里插入图片描述

若其中一个值没设置成功,其他值都设置不成功。

1.12 获取指定起止位置的字符串(截取字符串)

命令:getrange key 起始位置 结束位置

在这里插入图片描述

注:下标从0开始,截取的字符串包含起始位置和结束位置。

1.13 覆盖指定偏移索引后的值

命令:setrange key 偏移值 value

在这里插入图片描述

注:从偏移位置开始(包含偏移位置)设置新的值。

1.14 设置值(给定过期时间)

命令:setex key 过期时间(秒) value

命令:psetex key 过期时间(毫秒)value

在这里插入图片描述

注:不推荐使用。后期可能会被官方移除。

原子操作描述

所谓原子操作是指不会被线程调度机制打断的操作。

这种操作一旦开始,就一直运行到结束,中间不会有任何context switch(切换到另外一个线程)。

  1. 在单线程中,能够在单条指令中完成的操作都可以认为是“原子操作”,因为中断只能发生于指令之间。
  2. 在多线程中,不能被其他进程(线程)打断的操作就叫原子操作。

Redis单命令的原子性主要得益于redis的单线程。所以自增自减操作是原子性的。

2. List(列表)

2.1 从列表头/尾插入一个或多个值

命令:lpush/rpush key value1 value2 value3…

在这里插入图片描述

  • lpush表示从列表左侧(头)插入值
  • rpush表示从列表右侧(尾)插入值

2.2 从列表头/尾吐出一个值

命令:lpop/rpop key

在这里插入图片描述

  • lpop表示从列表左侧(头)吐出一个值
  • rpop表示从列表右侧(尾)吐出一个值

注:值存在,键存在。值都没了,键也没了

2.3 按照索引下标范围获得元素(从左到右)

命令:lrange key start stop

在这里插入图片描述

注:索引下标从0开始。若索引从 0 到 -1表示取出所有元素

在这里插入图片描述

注:此时不是取出元素,列表大小不会变化

2.4 按照索引下标值获得元素(从左到右)

命令:lindex key index

在这里插入图片描述

2.5 获取列表长度

命令:llen key

在这里插入图片描述

2.6 在指定value值的前面/后面插入newvalue值

命令:linsert key BEFORE/AFTER value newvalue

在这里插入图片描述

2.7 从左边删除n个value(从左到右)

命令:lrem key n value

在这里插入图片描述

注:若指定的删除元素值不存在,则不会影响任何数据

2.8 将列表下标为index的值替换成value

命令:lset key index value

在这里插入图片描述

3. Set(集合)

3.1 将一个或多个member元素加入到集合key中,已经存在的member元素将被忽略

命令:sadd key value1 value2 …

在这里插入图片描述

3.2 取出集合的所有值

命令:smembers key

在这里插入图片描述

3.3 判断集合是否含有value值

命令:sismember key value

在这里插入图片描述

注:若有值则返回1,无值则返回0

3.4 获取集合的元素个数

命令:scard key

在这里插入图片描述

3.5 删除集合中的元素

命令:srem key value1 value2 …

在这里插入图片描述

3.6 随机从集合中吐出一个值

命令:spop key

在这里插入图片描述

注:吐出的值会从集合中删除

3.7 随机从集合中吐出n个值(不会影响原集合)

命令:srandmember key n

在这里插入图片描述

3.8 移动集合元素到另外一个集合

命令:smove source destination value

在这里插入图片描述

3.9 获取两个集合的交集元素

命令:sinter key1 keky2

在这里插入图片描述

3.10 获取两个集合的并集元素

命令:sunion key1 key2

在这里插入图片描述

3.11 获取两个集合的差集元素

命令:sdiff key1 key2

在这里插入图片描述

注:key1中的,不包含key2中的。

4. Hash(哈希表)

4.1 给集合中的field键赋值value

命令:hset key field value

在这里插入图片描述

4.2 从集合中的field取值value

命令:hget key field

在这里插入图片描述

4.3 批量设置hash的值

命令:hmset key field1 value1 field2 value2…

在这里插入图片描述

4.4 查询哈希表key中指定域field是否存在

命令:hexists key field

在这里插入图片描述

4.5 获取集合的所有field

命令:hkeys key

在这里插入图片描述

4.6 获取集合的所有value

命令:hvals key

在这里插入图片描述

4.7 为哈希表key中的域field的值加上增量increment

命令:hincrby key field increment

在这里插入图片描述

注:增量值可以为负值,表示减去多少

4.8 将哈希表key中的域field的值设置为value,当且仅当域field不存在

命令:hsetnx key field value

在这里插入图片描述

注:设置成功返回 1,失败返回 0。

5. SortedSet(有序集合)

5.1 将一个或多个member元素及其score值加入到有序集key当中

命令:zadd key score1 value1 score2 value2 …

在这里插入图片描述

5.2 获取有序集key中,下标在start ~ stop之间的元素

命令:zrange key start stop [WITHSCORES]

在这里插入图片描述

  • 若范围值为 0 ~ -1 表示返回全部值。
  • 若最后加上 WITHSCORES,表示连同score分值一起返回。

5.3 返回有序集key中,所有score值介于min 和 max 之间(包括等于 min 或 max)的成员

命令:zrangebyscore key min max [withscores] [limit offset count]

在这里插入图片描述

  • withscores:表示同时返回分值。
  • LIMIT 偏移值 个数:偏移值表示返回的结果偏移的个数;个数表示限制返回的结果条数。
  • 有序集成员按score值递增(从小到大)次序排列。

5.4 同上(从大到小排序)

命令:zrevrangebyscore key max min withscores limit offset count

在这里插入图片描述

5.5 为元素的score加上增量

zincrby key increment value

在这里插入图片描述

注:increment为增值。

5.6 删除该集合下指定值的元素

命令:zrem key value

在这里插入图片描述

5.7 统计该集合下,分数区间内的元素个数

命令:zcount key min max

在这里插入图片描述

5.8 返回该值在集合中的排名,从0开始

命令:zrank key value

在这里插入图片描述

注:排名从0开始,从小到大,依次递增。

文章访问量的排行榜(Zset)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值