游乐游手机版
首页/数据库/文章详情

Redis String类型计数命令与其他操作详解

时间:2026-07-23 20:23
Redis的String类型提供原子性计数命令(INCR、DECR等),基于单线程避免并发竞争。还支持APPEND追加、GETRANGE截取子串、SETRANGE覆盖操作,需注意字节与字符编码。该类型二进制安全,广泛用于计数器、缓存、分布式锁等场景。

String 字符串

聊到Redis,String类型绝对是出镜率最高的数据类型,没有之一。它简单归简单,但背后那些计数、追加、截取之类的操作,用好了能省不少事。下面咱们把常用的命令挨个过一遍,顺便聊聊实际场景中怎么用最顺手。

计数命令

INCR:针对value+1

这个命令顾名思义,就是把 key 对应的值当作数字,然后加 1。如果 key 本身不存在,Redis 会默认它的值是 0,然后再加 1,相当于直接设置成 1。但如果 key 里面存的东西不是整数,或者数值超出了 64 位有符号整型的范围,那就直接报错了,不会给你含糊。

语法:

INCR key

命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值:integer 类型的加完后的数值(64位/8字节表示的整数,相当于C++中的long long,Ja va中的long)。

示例:

127.0.0.1:6379> EXISTS mykey
(integer) 1
127.0.0.1:6379> INCR mykey
(error) ERR value is not an integer or out of range
127.0.0.1:6379> SET mykey "10"
OK
127.0.0.1:6379> INCR mykey
(integer) 11
127.0.0.1:6379> SET mykey "46756767986967967977987987"
OK
127.0.0.1:6379> INCR mykey
(error) ERR value is not an integer or out of range
127.0.0.1:6379> SET mykey 'not a number'
OK
127.0.0.1:6379> INCR mykey
(error) ERR value is not an integer or out of range
127.0.0.1:6379> del mykey
(integer) 0
127.0.0.1:6379> INCR mykey
(integer) 1

Redis中String类型的计数其他命令

INCRBY:针对value+n

跟 INCR 类似,只不过加多少由你指定。注意,你要是想减,也可以传一个负数进去,比如 INCRBY key -1,效果就相当于减1。不过 Redis 后来还是单独设计了 DECR 和 DECRBY 命令,因为光看名字,INCRBY 传负数总觉得别扭,不够“人性化”。

语法:

INCRBY key decrement

命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值:integer 类型的加完后的数值。

示例:

127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> EXISTS mykey
(integer) 0
127.0.0.1:6379> INCRBY mykey 3
(integer) 3
127.0.0.1:6379> SET mykey "10"
OK
127.0.0.1:6379> INCRBY mykey 3
(integer) 13
127.0.0.1:6379> INCRBY mykey "not a number"
(error) ERR value is not an integer or out of range
127.0.0.1:6379> INCRBY mykey 3
(integer) 16
127.0.0.1:6379> SET mykey "234293482390480948029348230948"
OK
127.0.0.1:6379> INCRBY mykey 3
(error) ERR value is not an integer or out of range
127.0.0.1:6379> SET mykey 'not a number'
OK
127.0.0.1:6379> INCRBY mykey 3
(error) ERR value is not an integer or out of range
127.0.0.1:6379> SET mykey "10"
OK
127.0.0.1:6379> INCRBY mykey -1
(integer) 9

Redis中String类型的计数其他命令

不过话说回来,虽然 INCRBY 传负数能实现减法,但设计上还是分开成了 DECR 和 DECRBY,毕竟从命名上更直观,谁也不想看到“加”命令里传个负数去减。

DECR:针对value-1

这个就是减1,跟 INCR 对应。同样,key 不存在就当作0,减完变成-1。

语法:

DECR key

命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值:integer 类型的减完后的数值。

示例:

127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> exists mykey
(integer) 0
127.0.0.1:6379> DECR mykey
(integer) -1
127.0.0.1:6379> SET mykey "10"
OK
127.0.0.1:6379> DECR mykey
(integer) 9
127.0.0.1:6379> SET mykey "767678678678564545454586867868678678"
OK
127.0.0.1:6379> DECR mykey
(error) ERR value is not an integer or out of range
127.0.0.1:6379> SET mykey 'not a number'
OK
127.0.0.1:6379> DECR mykey
(error) ERR value is not an integer or out of range

Redis中String类型的计数其他命令

DECRBY:针对value-n

顾名思义,减指定的数值。同样,key 不存在时当作0,然后减去你给的值。

语法:

DECRBY key decrement

命令有效版本:1.0.0 之后
时间复杂度:O(1)
返回值:integer 类型的减完后的数值。

示例:

127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> exists mykey
(integer) 0
127.0.0.1:6379> DECRBY mykey 3
(integer) -3
127.0.0.1:6379> SET mykey "10"
OK
127.0.0.1:6379> DECRBY mykey 3
(integer) 7
127.0.0.1:6379> DECRBY mykey "not a number"
(error) ERR value is not an integer or out of range
127.0.0.1:6379> DECRBY mykey 3
(integer) 4
127.0.0.1:6379> SET mykey "76879879879879878798676767676798"
OK
127.0.0.1:6379> DECRBY mykey 3
(error) ERR value is not an integer or out of range
127.0.0.1:6379> SET mykey 'not a number'
OK
127.0.0.1:6379> DECRBY mykey 3
(error) ERR value is not an integer or out of range

Redis中String类型的计数其他命令

INCRBYFLOAT:针对value+/-小数

这个命令是专门处理浮点数的,想加想减都行,传负数就是减。支持科学计数法,比如 5.0e3 表示5000。key 不存在时当作0,然后加你指定的浮点数。

语法:

INCRBYFLOAT key increment

命令有效版本:2.6.0 之后
时间复杂度:O(1)
返回值:加/减完后的数值。

示例:

127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> exists mykey
(integer) 0
127.0.0.1:6379> INCRBYFLOAT mykey 0.1
"0.1"
127.0.0.1:6379> SET mykey 10.50
OK
127.0.0.1:6379> INCRBYFLOAT mykey 0.1
"10.6"
127.0.0.1:6379> INCRBYFLOAT mykey -5
"5.6"
127.0.0.1:6379> SET mykey 5.0e3
OK
127.0.0.1:6379> INCRBYFLOAT mykey 2.0e2
"5200"
127.0.0.1:6379> SET mykey 10.50
OK
127.0.0.1:6379> INCRBYFLOAT mykey -50
"-39.5"

Redis中String类型的计数其他命令

很多存储系统内部用 CAS 机制实现计数,会有 CPU 开销,但在 Redis 里完全不用担心这个问题——因为 Redis 是单线程架构,命令都是顺序执行的,不存在并发竞争,计数操作天然就是原子性的。

其他命令

APPEND:追加子串

这个命令就是在字符串后面追加内容。如果 key 不存在,效果等同于 SET。注意,返回的是追加后字符串的长度,单位是字节。Redis 的字符串不关心字符编码,它只认识字节。比如你在 XShell 终端里输入汉字,默认是 UTF-8 编码,一个汉字通常占 3 个字节。所以追加汉字后,长度会按字节数增加。

语法:

APPEND KEY VALUE

命令有效版本:2.0.0 之后
时间复杂度:O(1)。追加的字符串一般长度较短,可以视为 O(1)
返回值:追加完成之后 string 的长度。

示例:

127.0.0.1:6379> exists mykey
(integer) 0
127.0.0.1:6379> APPEND mykey "Hello"
(integer) 5
127.0.0.1:6379> get mykey
"Hello"
127.0.0.1:6379> APPEND mykey "world"
(integer) 10
127.0.0.1:6379> get mykey
"Helloworld"
127.0.0.1:6379> APPEND mykey " hahaha"
(integer) 17
127.0.0.1:6379> get mykey
"Helloworld hahaha"
127.0.0.1:6379> APPEND mykey "哇"
(integer) 20
127.0.0.1:6379> get mykey
"Helloworld hahahaxe5x93x87"

Redis中String类型的计数其他命令

如果你在启动 Redis 客户端时加上 --raw 选项,客户端就会自动将二进制数据尝试翻译成可读的字符,比如汉字就能正常显示了:

127.0.0.1:6379> quit
root@yudukai:~# redis-cli --raw
127.0.0.1:6379> keys *
mykey
127.0.0.1:6379> get mykey
Helloworld hahaha哇
127.0.0.1:6379> 

Redis中String类型的计数其他命令

顺便提个小细节:操作 Linux 时,千万别乱按 Ctrl+S,这个快捷键在 XShell 里是“冻结当前画面”,按了之后终端会卡住不动,按 Ctrl+Q 才能解除冻结。

GETRANGE:返回范围子串

返回 key 对应字符串的一个子串,范围由 start 和 end 指定,注意是左闭右闭区间。可以用负数,-1 表示最后一个字符,-2 表示倒数第二个,以此类推。如果指定的范围超出字符串实际长度,Redis 会自动调整到合法范围。如果你切的是汉字,就得小心了——一个汉字在 UTF-8 下是 3 个字节,如果你从中间切开,出来的可能就不是正常字符了。

语法:

GETRANGE key start end

命令有效版本:2.4.0 之后
时间复杂度:O(N)。N 为 [start, end] 区间的长度。由于 string 通常比较短,可以视为是 O(1)
返回值:string 类型的子串。

示例:

127.0.0.1:6379> SET mykey "This is a string"
OK
127.0.0.1:6379> GETRANGE mykey 0 3
"This"
127.0.0.1:6379> GETRANGE mykey -3 -1
"ing"
127.0.0.1:6379> GETRANGE mykey 0 -1
"This is a string"
127.0.0.1:6379> GETRANGE mykey 10 100
"string"

Redis中String类型的计数其他命令

SETRANGE:覆盖范围子串

用指定的字符串从偏移量 offset 开始覆盖原字符串。如果 offset 超出了原字符串长度,Redis 会用空字节(\x00)填充中间的部分。如果 key 不存在,也会先创建空字符串再填充。

语法:

SETRANGE key offset value

命令有效版本:2.2.0 之后
时间复杂度:O(N),N 为 value 的长度。由于一般给的 value 比较短,通常视为 O(1)
返回值:替换后的 string 的长度。

示例:

127.0.0.1:6379> SET key1 "Hello World"
OK
127.0.0.1:6379> SETRANGE key1 6 "Redis"
(integer) 11
127.0.0.1:6379> get key1
"Hello Redis"
127.0.0.1:6379> setrange key1 1 a
(integer) 11
127.0.0.1:6379> get key1
"Hallo Redis"
127.0.0.1:6379> setrange key1 10 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
(integer) 57
127.0.0.1:6379> get key1
"Hallo Rediaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
127.0.0.1:6379> setrange key2 1 aaa
(integer) 4
127.0.0.1:6379> get key2
"\x00aaa"

Redis中String类型的计数其他命令

Redis中String类型的计数其他命令

Redis中String类型的计数其他命令

STRLEN:获取子串长度

返回 key 对应字符串的长度,单位是字节。注意,不是字符数。比如一个汉字在 UTF-8 下是 3 个字节,那 strlen 返回的就是 3。如果 key 不存在,返回 0。如果 key 存的不是字符串,会报错。

语法:

STRLEN key

命令有效版本:2.2.0 之后
时间复杂度:O(1)
返回值:string 的长度。或者当 key 不存在时,返回 0。

示例:

127.0.0.1:6379> exists mykey
(integer) 0
127.0.0.1:6379> SET mykey "Hello world"
OK
127.0.0.1:6379> strlen mykey
(integer) 11
127.0.0.1:6379> strlen nonexisting
(integer) 0

Redis中String类型的计数其他命令

命令小结

下面这张表汇总了字符串类型常用命令的效果和时间复杂度,开发时可以根据业务需求和数据大小选合适的命令。注意,O(k) 通常可以当作 O(1),因为 k 一般是你自己输入的值,不会太大。

Redis中String类型的计数其他命令

内部编码

Redis 字符串类型实际存储时,内部有三种编码方式:

  • int:8 个字节的长整型。
  • embstr:小于等于 39 个字节的字符串(在 Redis 3.0 之后,这个临界值是 44 字节)。适用于比较短的字符串。
  • raw:大于 39 个字节的字符串。

Redis 会根据当前值的类型和长度,动态选择最合适的编码方式。比如,整数直接用 int 存储,方便算术运算;小数则当作字符串存储,因为每次计算需要转换,性能不如整数。

整型示例:

127.0.0.1:6379> set key 666
OK
127.0.0.1:6379> object encoding key
"int"

短字符串示例:

127.0.0.1:6379> set key1 "hello"
OK
127.0.0.1:6379> object encoding key1
"embstr"
127.0.0.1:6379> set key8 1.5
OK
127.0.0.1:6379> object encoding key8
"embstr"

长字符串示例:

127.0.0.1:6379> set key2 "one string greater than 39 bytes ........"
OK
127.0.0.1:6379> object encoding key2
"embstr"
127.0.0.1:6379> set key3 "one string greater than 39 bytes ........................................................."
OK
127.0.0.1:6379> object encoding key3
"raw"
127.0.0.1:6379> set key4 "one string greater than 39 bytes ........."
OK
127.0.0.1:6379> object encoding key4
"embstr"
127.0.0.1:6379> set key5 "one string greater than 39 bytes .........."
OK
127.0.0.1:6379> object encoding key5
"embstr"
127.0.0.1:6379> set key6 "one string greater than 39 bytes ..........."
OK
127.0.0.1:6379> object encoding key6
"embstr"
127.0.0.1:6379> set key7 "one string greater than 39 bytes ............"
OK
127.0.0.1:6379> object encoding key7
"raw"

Redis中String类型的计数其他命令

典型使用场景

缓存(Cache)功能

这是 Redis 最经典的用法之一。Redis 作为缓冲层,MySQL 作为存储层,绝大部分请求的数据直接从 Redis 获取,只有缓存未命中时才会去查 MySQL。由于 Redis 支持高并发,缓存能显著加速读写,同时降低后端数据库的压力。

Redis中String类型的计数其他命令

下面的伪代码模拟了典型的业务数据访问流程:

  1. 根据用户 uid 获取用户信息。
UserInfo getUserInfo(long uid) {
    ...
}
  1. 先从 Redis 获取,假设用户信息保存在 "user:info:" 这个键中:
String key = "user:info:" + uid;
String value = Redis 执行命令:get key;
if (value != null) {
    // 假设用户信息是 JSON 格式
    UserInfo userInfo = JSON 反序列化(value);
    return userInfo;
}
  1. 如果缓存未命中,则从 MySQL 查询,然后写入 Redis 并返回:
if (value == null) {
    UserInfo userInfo = MySQL 执行 SQL:select * from user_info where uid = 
    if (userInfo == null) {
        响应 404
        return null;
    }
    String value = JSON 序列化(userInfo);
    // 设置过期时间 1 小时,防止数据腐烂
    Redis 执行命令:set key value ex 3600
    return userInfo;
}

理想情况下,每个用户信息每小时只需要查一次 MySQL,效率提升非常明显。这背后其实暗含了一个假设:某个数据一旦被访问,短时间内很可能被反复访问——也就是热点数据。

不过这个策略有个问题:随着时间的推移,Redis 里的 key 会越来越多,内存肯定扛不住。解决办法有两个:一是给每个 key 设置过期时间;二是依赖 Redis 本身的内存淘汰策略,在内存不足时自动清理不常用的数据。

另外,关于键名的设计,Redis 没有表、字段这种命名空间,所以键名最好有清晰的业务含义。推荐格式:业务名:对象名:唯一标识:属性。比如 vs:user_info:6379:name。如果当前 Redis 只服务一个业务,可以省略业务名。如果键名过长,可以用团队内约定的缩写,比如 user:6379:friends:messages:5217 可以缩写成 u:6379:fr:m:5217,毕竟过长的键名会影响性能。

计数(Counter)功能

很多应用用 Redis 做计数工具,比如视频播放次数、点赞数等。用户每播放一次视频,对应的计数就自增 1。Redis 的 INCR 命令是原子操作,非常方便。

Redis中String类型的计数其他命令

long incrVideoCounter(long vid) {
    key = "video:" + vid;
    long count = Redis 执行命令:incr key
    return counter;
}

当然,真实的计数系统要考虑的远不止这些:防作弊、多维度统计、高可用、数据持久化等等,但 Redis 作为计数底座,地位不可替代。

共享会话(Session)

在分布式 Web 服务中,如果每个服务器各自保存用户的 Session 信息,就会出现一个问题:用户请求被负载均衡到不同服务器时,可能因为 Session 不共享而需要重新登录。解决办法是把 Session 集中存到 Redis 里,所有 Web 服务器都从 Redis 读写 Session,这样无论请求落到哪台机器,体验都一致。

Redis中String类型的计数其他命令

Redis中String类型的计数其他命令

手机验证码

很多 App 在登录时要求输入手机号并接收验证码,为了防止刷信息,通常会限制每分钟发送次数,比如不能超过 5 次。用 Redis 可以轻松实现这个限流逻辑:

Redis中String类型的计数其他命令

伪代码说明:

String 发送验证码(phoneNumber) {
    key = "shortMsg:limit:" + phoneNumber;
    // 设置过期时间为 1 分钟,使用 NX 确保只有第一次能设置成功
    bool r = Redis 执行命令:set key 1 ex 60 nx
    if (r == false) {
        // 说明之前已经设置过,计数加 1
        long c = Redis 执行命令:incr key
        if (c > 5) {
            // 超过限制,返回 null
            return null;
        }
    }
    String validationCode = 生成随机的 6 位数的验证码();
    validationKey = "validation:" + phoneNumber;
    // 验证码 5 分钟有效
    Redis 执行命令:set validationKey validationCode ex 300;
    return validationCode;
}

bool 验证验证码(phoneNumber, validationCode) {
    validationKey = "validation:" + phoneNumber;
    String value = Redis 执行命令:get validationKey;
    if (value == null) {
        return false;
    }
    return value.equals(validationCode);
}

以上只是字符串类型的几个典型场景。实际开发中,只要理解了它的特点——简单、高效、原子性,再加上一点点想象力,很多业务场景都能找到用武之地。

来源:https://www.jb51.net/database/367930fv0.htm
上一篇Redis主从配置与哨兵故障转移高可用完整方案 下一篇PostgreSQL索引策略:从慢查询到毫秒响应的工程实践
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
自增主键值从何而来?深入理解原理,告别只会auto_increment
数据库 · 2026-07-25

自增主键值从何而来?深入理解原理,告别只会auto_increment

KingbaseES推荐使用serial、bigserial、显式sequence或identity列实现自增主键。serial创建integer并关联序列,bigserial对应bigint;显式sequence可自定义起始值等参数;identity有generatedbydefault(允许指定值)与always(禁止)两种模式。

Linux下瀚高数据库授权文件过期及替换解决方案
数据库 · 2026-07-25

Linux下瀚高数据库授权文件过期及替换解决方案

在银河麒麟系统下,瀚高数据库hgdb-4 5试用授权20天到期后需替换正式授权文件。正确操作:停止服务,备份旧文件,将授权文件复制到 opt highgo hgdb-4 5 etc lic 并命名为hgdb lic,设置权限600和属主highgo:highgo,再启动服务。禁止直接修改data目录下的license info文件。

Oracle BLOB实时同步的5大技术挑战与难点解析
数据库 · 2026-07-25

Oracle BLOB实时同步的5大技术挑战与难点解析

OracleBLOB实时同步面临分片组装、多列隔离、长事务跨窗口、事务回滚及大对象资源控制等技术挑战,必须在日志中精确还原完整字段值,才能保证源端与目标端数据完全一致,这对同步系统的稳健性提出了高要求。

MySQL禁用redo日志导致全备失败
数据库 · 2026-07-25

MySQL禁用redo日志导致全备失败

MySQL全量备份失败是由于数据定义语言操作触发排序索引构建,禁用重做日志导致XtraBackup无法获取一致性备份。测试验证表明,优化表语句即使无数据也会触发该问题。根本原因在于排序索引构建过程跳过了重做日志记录,破坏了备份的一致性。

Kafka架构图优化与改进的全面详细步骤与实践指南
数据库 · 2026-07-25

Kafka架构图优化与改进的全面详细步骤与实践指南

Kafka作为实时数据流处理的核心中间件,其底层架构虽已相当成熟,但在实际生产环境中,要充分发挥其性能潜力,仍需落实到具体的调优与架构改造上。核心目标可归纳为三点:如何承载更高的吞吐量、如何保障数据不丢失、以及故障发生时如何快速恢复。本文将从这几个关键方向出发,深入探讨如何真正榨干Kafka集群的性