前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis面试(二):数据结构

Redis面试(二):数据结构

原创
作者头像
传说之下的花儿
发布2023-09-21 08:27:19
2730
发布2023-09-21 08:27:19
举报

2. 数据结构

2.1 Redis有哪些数据结构?

Redis有以下这五种基本类型:

  • String(字符串):SDS 简单动态字符串
  • List(列表):SDS 简单动态字符串
  • Hash(字典):哈希表、压缩列表
  • Set(集合):哈希表、整数集合
  • zset(有序集合):压缩列表、skiplist 跳表

它还有三种特殊的数据结构类型

  • Bitmap(位存储):用一个比特位来映射某个元素的状态,在Redis中,它的底层是基于字符串类型实现的,可以把bitmaps成作一个以比特位为单位的数组。
  • Geospatial(地理位置):地理位置定位,用于存储地理位置信息,并对存储的信息进行操作。
  • Hyperloglog(基数统计):用来做基数统计算法的数据结构,如统计网站的UV。
2.1.1 String(SDS)
1. 介绍

String 是最常用的一种数据类型,普通的 key- value 存储都可以归为此类。其中 Value 既可以是数字也可以是字符串。使用场景:常规 key-value 缓存应用。常规计数: 微博数, 粉丝数。

底层结构:SDS(简单动态字符串)

虽然 Redis 是用 C 语言写的,但是 Redis 并没有使用 C 的字符串表示,而是自己构建了一种 简单动态字符串(Simple Dynamic String,SDS)。

相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本数据还可以保存二进制数据,并且获取字符串长度复杂度为 O(1)(C 字符串为 O(N)), 除此之外,Redis 的 SDS API 是安全的,不会造成缓冲区溢出。

SDS结构如下:

代码语言:javascript
复制
 struct sdshdr{ 
     unsigned int len;   // 记录buf数组中已使用字节的数量
     unsigned int free;  // 记录 buf 数组中未使用字节的数量 
     char buf[];         // 字节数组,用于保存字符串
 }

SDS 结构图如下:

2. 常用命令

命令

介绍

SET key value

设置指定 key 的值

SETNX key value

只有在 key 不存在时设置 key 的值

GET key

获取指定 key 的值

MSET key1 value1 key2 value2 …

设置一个或多个指定 key 的值

MGET key1 key2 ...

获取一个或多个指定 key 的值

STRLEN key

返回 key 所储存的字符串值的长度

INCR key

将 key 中储存的数字值增一

DECR key

将 key 中储存的数字值减一

EXISTS key

判断指定 key 是否存在

DEL key(通用)

删除指定的 key

EXPIRE key seconds(通用)

给指定 key 设置过期时间

3. 应用场景
  1. 需要存储常规数据的场景:
    • 举例 :缓存 session、token、图片地址、序列化后的对象 (相比较于 Hash 存储更节省内存)。
    • 相关命令 : SET、GET
  2. 需要计数的场景:
    • 举例 :用户单位时间的请求数(简单限流可以用到)、页面单位时间的访问数。
    • 相关命令 :SET、GET、INCR、DECR
  3. 分布式锁: 利用 SETNX key value 命令可以实现一个最简易的分布式锁(存在一些缺陷,通常不建议这样实现分布式锁)
2.1.2 Hash(压缩列表、哈希表)
1. 介绍

哈希是一种键值对的集合,其中每个键都对应一个值。哈希适合存储对象或实体的相关属性,可以快速进行单个字段的读写操作。底层实现使用哈希表来存储。

底层结构:ziplist(压缩列表)、hashmap(哈希表)

字符串和哈希类型对比如下图:

2. 常用命令

HSET key field value

设置指定哈希表中指定字段的值

HSETNX key field value

只有指定字段不存在时设置指定字段的值

HMSET key field1 value1 field2 value2 ...

同时将一个或多个 field-value (域 - 值) 对设置到指定哈希表中

HGET key field

获取指定哈希表中指定字段的值

HMGET key field1 field2 ...

获取指定哈希表中一个或者多个指定字段的值

HGETALL key

获取指定哈希表中所有的键值对

HEXISTS key field

查看指定哈希表中指定的字段是否存在

HDEL key field1 field2 ...

删除一个或多个哈希表字段

HLEN key

获取指定哈希表中字段的数量

HINCRBY key field increment

对指定哈希中的指定字段做运算操作(正数为加,负数为减)

3. 应用场景
  1. 对象数据存储场景:
    • 举例 :用户信息、商品信息、文章信息、购物车信息。
    • 相关命令 :HSET (设置单个字段的值)、HMSET(设置多个字段的值)、HGET(获取单个字段的值)、HMGET(获取多个字段的值)
2.1.3 List(压缩列表、双向链表)
1. 介绍

列表(list)类型是用来存储多个有序的字符串,一个列表最多可以存储2^32-1个元素。

底层结构:ziplist(压缩列表)、linkedlist(双向链表)

一图看懂list类型的插入与弹出:

List应用场景参考以下:

  • lpush+lpop=Stack(栈)
  • lpush+rpop=Queue(队列)
  • lpsh+ltrim=Capped Collection(有限集合)
  • lpush+brpop=Message Queue(消息队列)
2. 常用命令

命令

介绍

RPUSH key value1 value2 ...

在指定列表的尾部(右边)添加一个或多个元素

LPUSH key value1 value2 ...

在指定列表的头部(左边)添加一个或多个元素

LSET key index value

将指定列表索引 index 位置的值设置为 value

LPOP key

移除并获取指定列表的第一个元素 (最左边)

RPOP key

移除并获取指定列表的最后一个元素 (最右边)

LLEN key

获取列表元素数量

LRANGE key start end

获取列表 start 和 end 之间 的元素

3. 应用场景
  1. 信息流展示:
    • 举例 :最新文章、最新动态。
    • 相关命令 : LPUSH、LRANGE。
  2. 消息队列: Redis List 数据结构可以用来做消息队列,只是功能过于简单且存在很多缺陷,不建议这样做。 相对来说,Redis 5.0 新增加的一个数据结构 Stream 更适合做消息队列一些,只是功能依然非常简陋。和专业的消息队列相比,还是有很多欠缺的地方比如消息丢失和堆积问题不好解决。
2.1.4 Set(整数集合、哈希表)
1. 介绍

Redis 中的 Set 类型是一种无序集合,集合中的元素没有先后顺序但都唯一。

当你需要存储一个列表数据,又不希望出现重复数据时,Set 是一个很好的选择,并且 Set 提供了判断某个元素是否在一个 Set 集合内的重要接口,这个也是 List 所不能提供的。

你可以基于 Set 轻易实现交集、并集、差集的操作,比如你可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。这样的话,Set 可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程。

底层结构:intset(整数集合)hashtable(哈希表)

2. 常用命令

命令

介绍

SADD key member1 member2 ...

向指定集合添加一个或多个元素

SMEMBERS key

获取指定集合中的所有元素

SCARD key

获取指定集合的元素数量

SISMEMBER key member

判断指定元素是否在指定集合中

SINTER key1 key2 ...

获取给定所有集合的交集

SINTERSTORE destination key1 key2 ...

将给定所有集合的交集存储在 destination 中

SUNION key1 key2 ...

获取给定所有集合的并集

SUNIONSTORE destination key1 key2 ...

将给定所有集合的并集存储在 destination 中

SDIFF key1 key2 ...

获取给定所有集合的差集

SDIFFSTORE destination key1 key2 ...

将给定所有集合的差集存储在 destination 中

SPOP key count

随机移除并获取指定集合中一个或多个元素

SRANDMEMBER key count

随机获取指定集合中指定数量的元素

3. 应用场景
  1. 需要存放的数据不能重复的场景
    • 举例:网站 UV 统计(数据量巨大的场景还是 HyperLogLog 更适合一些)、文章点赞、动态点赞等场景。
    • 相关命令:SCARD(获取集合数量)
  2. 需要获取多个数据源交集、并集和差集的场景
    • 举例 :共同好友 (交集)、共同粉丝 (交集)、共同关注 (交集)、好友推荐(差集)、音乐推荐(差集) 、订阅号推荐(差集 + 交集) 等场景。
    • 相关命令:SINTER(交集)、SINTERSTORE(交集)、SUNION (并集)、SUNIONSTORE(并集)、SDIFF(差集)、SDIFFSTORE (差集)。
    • 集合类型比较典型的使用场景是标签 (tag). 例如一个用户可能对音乐感兴趣, 另一个用户对新闻感兴趣, 这些想去点就是标签. 有了这些数据就可以获得喜欢同一个标签的人, 以及用户的共同喜好的标签, 这些数据对于用户体验来说比较重要.
  3. 需要随机获取数据源中的元素的场景:
    • 举例 :抽奖系统、随机。
    • 相关命令:SPOP(随机获取集合中的元素并移除,适合不允许重复中奖的场景)、SRANDMEMBER(随机获取集合中的元素,适合允许重复中奖的场景)
2.1.5 Zset(压缩列表、跳跃表)
1. 介绍

Sorted Set 类似于 Set,但和 Set 相比,Sorted Set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。

底层结构:ziplist(压缩列表)skiplist(跳跃表)

2. 常用命令

命令

介绍

ZADD key score1 member1 score2 member2 ...

向指定有序集合添加一个或多个元素

ZCARD KEY

获取指定有序集合的元素数量

ZSCORE key member

获取指定有序集合中指定元素的 score 值

ZINTERSTORE destination numkeys key1 key2 ...

将给定所有有序集合的交集存储在 destination 中,对相同元素对应的 score 值进行 SUM 聚合操作,numkeys 为集合数量

ZUNIONSTORE destination numkeys key1 key2 ...

求并集,其它和 ZINTERSTORE 类似

ZDIFF destination numkeys key1 key2 ...

求差集,其它和 ZINTERSTORE 类似

ZRANGE key start end

获取指定有序集合 start 和 end 之间的元素(score 从低到高)

ZREVRANGE key start end

获取指定有序集合 start 和 end 之间的元素(score 从高到底)

ZREVRANK key member

获取指定有序集合中指定元素的排名 (score 从大到小排序)

3. 应用场景
  1. 需要随机获取数据源中的元素根据某个权重进行排序的场景:
    • 举例 :各种排行榜比如直播间送礼物的排行榜、朋友圈的微信步数排行榜、王者荣耀中的段位排行榜、话题热度排行榜等等。
    • 相关命令 :ZRANGE (从小到大排序) 、 ZREVRANGE (从大到小排序)、ZREVRANK (指定元素排名)。
  2. 需要存储的数据有优先级或者重要程度的场景:
    • 举例 :优先级任务队列。
    • 相关命令 :ZRANGE (从小到大排序) 、 ZREVRANGE (从大到小排序)、ZREVRANK (指定元素排名)。

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.1 Redis有哪些数据结构?
    • 2.1.1 String(SDS)
      • 1. 介绍
      • 2. 常用命令
      • 3. 应用场景
    • 2.1.2 Hash(压缩列表、哈希表)
      • 1. 介绍
      • 2. 常用命令
      • 3. 应用场景
    • 2.1.3 List(压缩列表、双向链表)
      • 1. 介绍
      • 2. 常用命令
      • 3. 应用场景
    • 2.1.4 Set(整数集合、哈希表)
      • 1. 介绍
      • 2. 常用命令
      • 3. 应用场景
    • 2.1.5 Zset(压缩列表、跳跃表)
      • 1. 介绍
      • 2. 常用命令
      • 3. 应用场景
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档