当前位置: 首页 > news >正文

redis---string类型详解

Redis 的 string(字符串)类型是最基础也最常用的数据类型,它不仅能存储文本字符串,还能存储二进制数据和数字,具有灵活高效的特点。

一、底层原理

Redis 的 string 类型并非直接使用 C 语言的原生字符串(以 \0 结尾的字符数组),而是采用了简单动态字符串(SDS,Simple Dynamic String) 结构,定义如下(简化版):

struct sdshdr {int len;       // 已使用字节数(字符串长度)int free;      // 未使用字节数(空闲空间)char buf[];    // 字符数组(存储实际数据)
};

SDS 的优势

  1. O (1) 时间获取长度:通过 len 属性直接获取,无需像 C 字符串那样遍历。
  2. 预分配空间:修改字符串时会预留 free 空间,减少内存重分配次数(如字符串增长时)。
  3. 二进制安全:不依赖 \0 标识结尾,可存储图片、视频等二进制数据。
  4. 杜绝缓冲区溢出:修改时会先检查空间是否足够,不足则自动扩容。

二、基本特性

  1. 存储范围

    • 最大长度为 512MB(包括文本、二进制数据等)。
    • 可存储:普通字符串(如 "hello")、数字(如 123)、二进制数据(如序列化的对象)。
  2. 原子性操作:所有 string 类型的命令都是原子性的,适合作为计数器、锁等场景。

三、常用命令

1. 基础操作
  • SET key value [EX seconds] [PX milliseconds] [NX|XX]
    设置键值对。

    • 选项:EX(过期时间,秒)、PX(过期时间,毫秒)、NX(键不存在时才设置,否则返回nil)、XX(键存在时才设置,否则返回nil)。
      示例:SET name "redis" EX 3600(设置 name 为 "redis",1 小时后过期)。

  • GET key
    获取键对应的值。若键不存在,返回 nil

    对于除string的value来说,使用get会报错       
  •   示例:GET name → "redis"。

扩展:

# 清空所有数据库的所有数据
FLUSHALL

DEL key
删除键。返回被删除的键数量。
示例:DEL name → 1。

  • EXISTS key
    判断键是否存在。返回 1(存在)或 0(不存在)。

2. 批量操作
  • MSET key1 value1 key2 value2 ...
    批量设置键值对(原子操作)。
    示例:MSET a 1 b 2

  • MGET key1 key2 ...
    批量获取值,返回值的顺序与键的顺序一致。
    示例:MGET a b → [1, 2]。

3. 数字操作(自增 / 自减)
  • INCR key
    对值进行自增 1(值必须是整数)。返回自增后的值。
    示例:INCR count → 1(若初始值为 0)。

  • DECR key
    对值进行自减 1。返回自减后的值。

  • INCRBY key increment
    自增指定整数(如 INCRBY count 5 表示 +5)。

  • DECRBY key decrement
    自减指定整数。

  • INCRBYFLOAT key increment
    自增指定浮点数(如 INCRBYFLOAT score 0.5)。

4. 字符串修改
  • APPEND key value
    向字符串末尾追加内容。返回追加后的总长度。
    示例:APPEND name "db" → 6(原 name 为 "redis",追加后为 "redisdb")。

  • STRLEN key
    获取字符串长度(字节数)。
    示例:STRLEN name → 6。

  • SUBSTR key start end

  • GETRNGE key start end
    截取子字符串(下标从 0 开始,end 为闭区间)。

    • 支持下标为负数

  • 示例:SUBSTR name 0 2 → "red"。

  • Redis 的 SETRANGE 命令用于从指定偏移量(下标开始)覆盖字符串的值,即修改字符串中特定位置的字符。它可以对已存在的字符串进行部分更新,而无需替换整个字符串。

    基本语法

    bash

    SETRANGE key offset value

扩展:

redis-cli --raw

Ctrl+s在xshell中是冻结画面的效果

Ctrl+q解除冻结画面

5. 过期与生存时间
  • EXPIRE key seconds
    设置键的过期时间(秒)。
    示例:EXPIRE code 60(60 秒后过期)。

  • TTL key
    查看键的剩余生存时间(秒)。返回 -1(永不过期)、-2(已过期 / 不存在)。

四、内部编码

Redis 的 string 类型(字符串)在底层有三种不同的内部编码方式,Redis 会根据字符串的长度和内容自动选择最合适的编码,以优化内存占用和操作效率。这三种编码分别是:

1. int 编码

  • 适用场景:当字符串的值是64 位有符号整数(范围:-9223372036854775808 至 9223372036854775807)时使用。
  • 存储方式:直接以整数形式存储,而非字符数组,节省内存空间。
  • 示例SET num 12345 → 内部用 int 编码存储。

2. embstr 编码

  • 适用场景:当字符串是短字符串(长度 ≤ 44 字节,Redis 3.2+ 标准),且内容不是整数时使用。
  • 存储方式
    • embstr 是 "embedded string" 的缩写,将字符串的元数据(长度、空闲空间等)和实际数据连续存储在同一块内存中。
    • 相比 raw 编码,减少了内存分配次数(一次分配即可),且数据在内存中连续,有利于 CPU 缓存。
  • 示例SET str "hello world"(长度 11 字节)→ 内部用 embstr 编码。

3. raw 编码

  • 适用场景:当字符串是长字符串(长度 > 44 字节),或短字符串经过修改后长度超过阈值时使用。
  • 存储方式
    • 元数据和实际数据分开存储在不同的内存块中。
    • 适合存储较长的文本或二进制数据(如序列化对象、图片等)。
  • 示例SET longstr "a...a"(长度 100 字节)→ 内部用 raw 编码。

编码转换规则

Redis 会根据字符串的内容和操作自动转换编码,规则如下:

  1. int → raw:当整数被修改为非整数(如追加字符串)时,会转为 raw 编码。
    示例:SET num 123int)→ APPEND num "abc" → 变为 "123abc"(raw)。

  2. embstr → rawembstr 是只读的,一旦被修改(如 APPENDSETRANGE 等),会转为 raw 编码。
    示例:SET str "hello"embstr)→ APPEND str " world" → 变为 "hello world"(若长度超过 44 字节则转为 raw)。

  3. raw 不会转回 embstr 或 int:一旦转为 raw 编码,即使后续修改使字符串变短或成为整数,也不会再转回更节省内存的编码。

为什么需要多种编码?

  • 内存优化:短字符串用 embstr 减少内存碎片,整数用 int 直接存储,避免字符数组的冗余。
  • 性能优化embstr 的连续内存布局提升访问速度,raw 适合处理长字符串的灵活修改。

查看内部编码的方法

使用 OBJECT ENCODING key 命令可查看指定键的内部编码:

SET num 123
OBJECT ENCODING num  # 输出 "int"SET str "hello"
OBJECT ENCODING str  # 输出 "embstr"SET longstr "a"*100  # 100个"a"
OBJECT ENCODING longstr  # 输出 "raw"

http://www.dtcms.com/a/347733.html

相关文章:

  • 大模型四种常见安全问题与攻击案例
  • mysql的mvcc
  • 大语言模型应用开发——利用OpenAI函数与LangChain结合从文本构建知识图谱搭建RAG应用全流程
  • Redis全面详解:从配置入门到实战应用
  • 【前端debug调试】
  • 【Java SE】抽象类、接口与Object类
  • 从“一指禅”到盲打:如何系统提升电脑输入能力?
  • 25.深入对象
  • 联邦学习之----联邦批量归一化(FedBN)
  • 线程间Bug检测工具Canary
  • Python字符串
  • SOC估算方法-蜣螂优化算法结合极限学习
  • 1200 SCL学习笔记
  • 机器人控制基础:串级PID控制算法的参数如何整定?
  • 11.Shell脚本修炼手册---IF 条件语句的知识与实践
  • 无线数传模块保障智能立体车库多设备实时通信的可靠性
  • 二、BPMNJS简介
  • share logic in core or in example
  • 【typenum】 23 倒序存储的无符号整数(private.rs片段)
  • Linux mount 命令
  • PyInstaller将.py文件转为exe,执行文件在不同的电脑出现字体大小不一致问题原因分析及解决办法
  • Spring:IOC(控制反转 )、DI(依赖注入 )、AOP(通知类型、事务、拦截器)
  • 主流.NET 平台的NuGet 生态正在积极拥抱 AOT
  • 【84页PPT】智慧方案某著名企业某集团协同OA整体解决方案(附下载方式)
  • MySQL索引原理与优化全解析
  • 【每天一个知识点】训推一体机
  • 13.Shell脚本修炼手册---玩转 CASE 语句(应用场景与实践技巧)
  • GitHub Actions workflow最佳实践
  • 提问:温度不改变 logits 与概率的排名,为何还会影响模型输出?
  • Linux 进程间通信之System V 共享内存