前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis数据结构:String类型全面解析

Redis数据结构:String类型全面解析

作者头像
栗筝i
发布2023-10-16 14:34:38
4600
发布2023-10-16 14:34:38
举报
文章被收录于专栏:迁移内容

Redis,作为一个开源的、内存中的数据结构存储系统,以其出色的性能和灵活的数据类型,广泛应用于缓存、消息队列、发布订阅系统等多种场景。在 Redis 的五种基本数据类型中, String 类型是最基本也是最常用的一种。它不仅可以存储字符串,还可以存储整数和浮点数,甚至可以执行原子操作,如自增和自减。这使得 Redis 的 String 类型在实际应用中有着广泛的用途,从简单的键值对存储,到复杂的实时系统,都离不开 String 类型的支持。 在接下来的文章中,我将详细介绍 Redis 的 String 类型,包括它的内部实现、主要特性、常用命令以及应用场景。无论你是刚接触 Redis 的新手,还是已经有一定经验的开发者,我相信你都能从这篇文章中学到一些有用的知识。让我们一起深入了解 Redis 的 String 类型,探索它的魅力所在。

1、String数据类型
1.1、String类型简介

Redis 的 String 数据类型是最基本的数据类型,它在内部使用 SDS(Simple Dynamic String)实现。String 类型的值可以是字符串、整数或者浮点数,并且可以对整个字符串或者字符串的其中一部分执行操作。

以下是 Redis String 数据类型的一些主要特性:

  1. 二进制安全:String 类型的值可以包含任何数据,例如 jpg 图片或者序列化的对象,因为Redis不会对字符串类型的值做任何解析,而是将其看作是一个字节数组;
  2. 最大容量:Redis 的 String 类型的值最大可以存储 512MB 的内容;
  3. 原子操作:Redis 的很多操作都是原子的,也就是说,这些操作要么全部执行,要么全部不执行,不会出现部分执行的情况。这对于并发环境下的操作是非常有用的;
  4. 整数和浮点数操作:Redis 提供了一些操作,可以将字符串解析为整数或者浮点数,并执行自增或者自减操作
1.2、String应用场景

Redis 的 String 数据类型作为最基本的数据类型,它的应用场景非常广泛,以下是一些常见的应用场景:

  1. 缓存:由于Redis的高性能特性,String类型常常被用作缓存,可以将数据库查询结果、网页内容、会话信息等缓存在Redis中,提高系统的读取速度;
  2. 计数器:Redis的String类型可以将值解析为整数,并提供了自增(INCR)和自减(DECR)操作,因此可以作为各种计数器使用,例如网页访问量、下载量等;
  3. 分布式锁:通过 “SET key value”(只有当 key 不存在时才设置 value)命令,可以实现分布式锁,保证系统的并发安全;
  4. 分布式共享:可以将需要在多个系统间共享的数据存储在 Redis 的 String 类型中,例如用户的会话信息等;
  5. 限流:通过 INCR 命令和 EXPIRE 命令,可以实现 API 的限流功能,防止系统被过度访问,例如以访问者的 ip 和其他信息作为 key,访问一次增加一次计数,超过次数则返回 false

以上只是一些常见的应用场景,实际上,由于 Redis 的灵活性,我们可以根据自己的需求,将 Redis 的 String 类型应用在更多的场景中。

2、String底层结构
2.1、SDS介绍

Redis 使用 SDS 简单动态字符串(Simple Dynamic String,SDS)来表示字符串,Redis 中字符串类型包含的数据结构有:“整数(R_INT)” 与 “字符串(R_RAW)”

SDS 被广泛应用在 Redis 的各个地方,包括:

  1. 作为字符串对象的底层实现:在 Redis 中,所有的键都是字符串,而值可以是五种类型之一,其中包括字符串类型。这些字符串类型的键和值都是由 SDS 实现的;
  2. 作为缓冲区:Redis 的客户端和服务器在进行通信时,会使用 SDS 作为输入缓冲区和输出缓冲区,用于存储待发送的命令或者待返回的结果;
  3. 作为 AOF 模块的缓冲区:Redis 的 AOF(Append Only File,只追加文件)持久化功能,会把所有修改数据库的命令追加到 AOF 文件的末尾。在追加命令时,Redis 会先把命令追加到一个 SDS 中,然后再把 SDS 写入到 AOF 文件。
2.2、SDS结构

SDS(Simple Dynamic String,简单动态字符串)是 Redis 自己构建的抽象字符串类型,其在 C 语言原生字符串类型的基础上进行了一些改进和扩展。SDS 的主要结构如下:

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

属性

说明

“Free”

表示 Buf 数组中未使用字节的数量,也就是 Buf 数组的剩余空间。这样可以在增加字符串长度时,避免频繁的内存重新分配

“Len”

表示 Buf 数组中已使用字节的数量,也就是字符串的长度。这样可以在 O(1) 的时间复杂度内获取字符串长度,而不需要像 C 语言字符串那样遍历整个字符串

“Buf[]”

字节数组,用于保存字符串。这个数组的末尾总是包含一个空字符(‘\0’),这样 SDS 就可以兼容 C 语言的字符串函数

这种设计使得 SDS 在保持与 C 语言字符串兼容的同时,具有更高的效率和更好的安全性。

C 字符串结构与 SDS 字符串结构对比图参照如下:

image-20230813124658755
image-20230813124658755
2.3、SDS优点

SDS(Simple Dynamic String,简单动态字符串)作为 Redis 自己构建的抽象字符串类型,相比于 C 语言的字符串,它主要具有以下优点:

  1. 获取长度的时间复杂度为 O(1):SDS 内部维护了一个 len 属性,这个属性记录了字符串的长度,因此获取字符串长度的时间复杂度为 O(1),而 C 字符串需要遍历整个字符串才能获取到长度,时间复杂度为 O(n);
  2. 内存效率:SDS 通过维护一个 free 属性,记录了 buf 数组中未使用的字节数量,这样可以在需要扩展字符串时,直接使用这些未使用的空间,而不需要重新分配内存,提高了内存的使用效率;
  3. 避免缓冲区溢出:SDS在进行字符串修改操作时,会先检查缓冲区是否满足条件,如果不满足,会自动扩展缓冲区,因此可以避免缓冲区溢出的问题。而C字符串则需要程序员自己保证不会发生缓冲区溢出;
  4. 减少内存重新分配的次数:SDS通过空间预分配和惰性空间释放两种策略,减少了内存重新分配的次数。空间预分配是在修改字符串时,如果需要改变字符串长度,除了为修改后的字符串分配所需的空间外,还会分配额外的未使用空间;惰性空间释放是在缩短字符串时,不立即释放多余的空间,而是等待将来使用。这两种策略都可以减少内存重新分配的次数,提高效率;
  5. 二进制安全:C 字符串是以空字符 ‘\0’ 作为结束标志,因此不能正确存储包含 ‘\0’ 的字符串。而 SDS 的每一个字符都可以是 ‘\0’,因此 SDS 可以存储任何二进制数据;
  6. 兼容部分 C 字符串函数:SDS 在保证自身特性的同时,仍然保留了对部分 C 字符串函数的兼容性,这样可以方便地在 SDS 和 C 字符串之间进行转换。

3、String常用命令
3.1、设定操作

在 Redis 中,设定和获取 String 类型的 key 值主要使用以下命令:

代码语言:javascript
复制
SET key value

这个命令用于设定一个 key 的值。如果 key 已经存在,那么这个命令会覆盖原来的值。

image-20230826120759605
image-20230826120759605
3.2、获取操作

在 Redis 中,获取 String 类型的 key 值主要使用以下命令:

代码语言:javascript
复制
GET key	

这个命令用于获取一个 key 的值。如果 key 不存在,那么这个命令会返回 nil。

image-20230826120958744
image-20230826120958744
3.3、自增/自减操作

自减/自增 Key 值:

代码语言:javascript
复制
INCR key							# 自增
DECR key							# 自减

String 类型除了可以存字符串也可以是数字。注意这里得是数字才可以进行

image-20230819234729301
image-20230819234729301

如果要带步长:

代码语言:javascript
复制
INCRBY key	num				# 自增
DECRBY key	num				# 自减
image-20230819234934419
image-20230819234934419
3.4、追加字符串

使用 append 追加字符串:

代码语言:javascript
复制
APPEND key addvalue

append 命令后但会当前 string 长度。

image-20230819233702727
image-20230819233702727
3.5、删除字符串

使用 del 删除字符串:

代码语言:javascript
复制
DEL key
DEL key1 key2 key3
image-20230819235218967
image-20230819235218967
3.6、截取字符串

使用 getrange 截取字符串:

代码语言:javascript
复制
getrange key start end
getrange key 0 -1						# 查询全部
image-20230819235823254
image-20230819235823254
3.7、替换字符串

使用 setrange 替换字符串::

代码语言:javascript
复制
setrange key num value
image-20230820000105855
image-20230820000105855
3.8、分布式锁设置

分布锁设置,只有在 key 不存在时设置 key 的值:

代码语言:javascript
复制
SETNX key value 	
image-20230820000733308
image-20230820000733308
3.9、设置过期时间

设置指定 key 的值,并将 key 的过期时间设为 seconds 秒:

代码语言:javascript
复制
SETEX key seconds value
image-20230820001035365
image-20230820001035365
3.10、批量操作设置

一次性设置多个:

代码语言:javascript
复制
MSET k1 v1 k2 v2 k3 v3

一次性获取多个:

代码语言:javascript
复制
MGET k1 k2 k3
image-20230820001549588
image-20230820001549588

一次性设置多个(事务),只要有一个失败,则都不成功:

代码语言:javascript
复制
MSETNX k1 v1 k2 v2 k3 v3
image-20230820001812549
image-20230820001812549
3.11、获取字符串长度

使用 strlen 获取字符串长度:

代码语言:javascript
复制
STRLEN key
image-20230819234040304
image-20230819234040304
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、String数据类型
    • 1.1、String类型简介
      • 1.2、String应用场景
      • 2、String底层结构
        • 2.1、SDS介绍
          • 2.2、SDS结构
            • 2.3、SDS优点
            • 3、String常用命令
              • 3.1、设定操作
                • 3.2、获取操作
                  • 3.3、自增/自减操作
                    • 3.4、追加字符串
                      • 3.5、删除字符串
                        • 3.6、截取字符串
                          • 3.7、替换字符串
                            • 3.8、分布式锁设置
                              • 3.9、设置过期时间
                                • 3.10、批量操作设置
                                  • 3.11、获取字符串长度
                                  相关产品与服务
                                  云数据库 Redis
                                  腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档