前言

String类型是Redis最基本的数据类型,也是Memcached唯一支持的类型,对于刚接触Redis的同学也可以轻松上手。Redis的key是String类型的,如果Value如果也是String类型,相当于把两个字符串映射起来,即key-value。这里字符串不仅仅是传统意义上的字符串,例如“hello world”,也可以是JSON、HTML等。下面我们就来学习下Redis String类型的相关命令。

SET

可用版本:>= 1.0.0

时间复杂度:O(1)

设置key-value映射;

如果key已经对应了一个value,再次set将会覆盖(包括过期时间);

如果没有指定过期时间,默认永不过期;

set提供了可选参数,后续介绍的部分命令是set加上可选参数后的简化版。

命令格式如下:

1
SET key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL] [NX|XX] [GET]

可选参数

  • EX seconds: 设置过期时间为seconds秒
  • PX milliseconds: 设置过期时间为milliseconds毫秒
  • EXAT timestamp: 设置过期时间戳(秒级)
  • PXAT milliseconds-timestamp:设置过期时间戳(毫秒级)
  • NX: key在数据库中不存在才保存数据
  • XX: key在Redis存在才会保存数据
  • KEEPTTL: 保留该key上次剩余的过期时间
  • GET: 返回该key对应的旧值,如果之前key不存在会返回空,如果key对应的旧值不是String类型,会返回错误。

返回值

  • “OK”:set命令执行成功的返回值

  • 空值(nil):由于设置了’NX'、‘XX’条件,导致set未执行成功时的返回值

  • 当set时使用了可选参数的GET命令时,有两种返回值:

    • 旧值:key之前存在,返回对应的旧值

    • 空值(nil):key之前不存在

示例1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 设置key value,成功返回“OK”
127.0.0.1:6379> set key1 value1	 
OK

 # 查询key1对应的值
127.0.0.1:6379> get key1				
"value1"

# 查询过期时间,默认永不过期
127.0.0.1:6379> ttl key1								
(integer) -1


# 设置key1对应value2,过期时间60秒,此时会覆盖历史数据
127.0.0.1:6379> set key1 value2 ex 60		
OK

127.0.0.1:6379> get key1
"value2"

# 剩余45秒过期
127.0.0.1:6379> ttl key1  
(integer) 45

示例2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 设置key1-value1
127.0.0.1:6379> set key1 value1
OK

# key1不存在时,设置为value2(key1存在,set失败)
127.0.0.1:6379> set key1 value2 nx
(nil)

# 当key2存在时才保存(当前key2不存在,set失败)
127.0.0.1:6379> set key2 value2 xx
(nil)

# key1存在,set成功
127.0.0.1:6379> set key1 value2 xx
OK
127.0.0.1:6379> get key1
"value2"

示例3:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 设置过期时间
127.0.0.1:6379> set key3 value3 ex 100
OK
127.0.0.1:6379> ttl key3
(integer) 79

# set时,保留旧值的过期时间
127.0.0.1:6379> set key3 value4 keepttl
OK
127.0.0.1:6379> ttl key3
(integer) 66

# get参数,返回旧值
127.0.0.1:6379> set key3 value5 get
"value4"

SETNX

可用版本:>= 1.0.0

时间复杂度:O(1)

SetNX: “SET if Not eXists”,当key不存在时才保存,相当于set命令中加入NX参数后的简化版。

命令格式如下:

1
SETNX key value

示例:

1
2
3
4
5
6
127.0.0.1:6379> setnx mykey "hello"
(integer) 1
127.0.0.1:6379> setnx mykey "world"
(integer) 0
127.0.0.1:6379> get mykey
"hello"

SETEX

可用版本:>= 2.0.0

时间复杂度:O(1)

设置key-value,并添加过期时间,相当于是set命令添加EX参数后的简化版。

命令格式如下:

1
SETEX key seconds value

SetEX是原子性操作,等同于在事务中执行如下命令:

1
2
SET mykey value   
EXPIRE mykey seconds # 设置过期时间

示例:

1
2
3
4
5
6
127.0.0.1:6379> setex name 60 lifelmy
OK
127.0.0.1:6379> get name
"lifelmy"
127.0.0.1:6379> ttl name
(integer) 54

PSETEX

可用版本:>= 2.6.0

时间复杂度:O(1)

PSETEX 和 SETEX 作用一样,都是设置过期时间,区别是:PSETEX 时间单位是毫秒,SETEX 是秒。

命令格式如下:

1
PSETEX key milliseconds value

示例:

1
2
3
4
5
6
7
# 设置过期时间10000毫秒(10s)
127.0.0.1:6379> psetex name 10000 lifelmy
OK

# 查看过期时间(毫秒级别)
127.0.0.1:6379> pttl name
(integer) 8288

GET

可用版本:>= 1.0.0

时间复杂度:O(1)

GET返回key对应的value;

如果key不存在则返回空(nil);

如果value不是string类型则会返回错误;

命令格式如下:

1
GET key

示例:

1
2
3
4
5
6
7
8
# get不存在的key
127.0.0.1:6379> get notexistkey
(nil)

127.0.0.1:6379> set name hello
OK
127.0.0.1:6379> get name
"hello"

GETSET

可用版本:>= 1.0.0

时间复杂度:O(1)

设置key-value,并返回key对应的旧值;

旧值不存在返回nil,旧值不是String类型则会报错。

命令格式如下:

1
GETSET key value

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 清空数据库
127.0.0.1:6379> flushdb
OK

# 不存在旧值,返回nil
127.0.0.1:6379> getset name hello
(nil)

# 返回旧值“hello”
127.0.0.1:6379> getset name world
"hello"

127.0.0.1:6379> get name
"world"

该命令可以与计数命令配合使用,当计数完毕后,我们想要获取最终结果,并将计数清零。

1
2
3
4
5
6
127.0.0.1:6379> incr count
(integer) 1
127.0.0.1:6379> incr count
(integer) 2
127.0.0.1:6379> getset count 0
"2"

GETDEL

可用版本:>= 6.2.0

时间复杂度:O(1)

获取key对应的value,然后将key删除;

如果key不存在返回nil,value不是String类型则会报错。

命令格式如下:

1
GETDEL key

示例:

1
2
3
4
5
6
127.0.0.1:6379> set name lifelmy
OK
127.0.0.1:6379> getdel name
"lifelmy"
127.0.0.1:6379> get name
(nil)

GETEX

可用版本:>= 6.2.0

时间复杂度:O(1)

获取key对应的value,同时为key设置过期时间,设置过期时间的参数与set一致。

命令格式如下:

1
GETEX key [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|PERSIST]

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> set name lifelmy
OK
127.0.0.1:6379> get name
"lifelmy"
127.0.0.1:6379> ttl name
(integer) -1

# getex,设置过期时间60s
127.0.0.1:6379> getex name ex 60
"lifelmy"
127.0.0.1:6379> ttl name
(integer) 52

STRLEN

可用版本:>= 2.2.0

时间复杂度:O(1)

返回key对应value的字符串长度;

key不存在返回0,value不是字符串类型则会报错。

命令格式如下:

1
STRLEN key

示例:

1
2
3
4
5
6
127.0.0.1:6379> set name lifelmy
OK
127.0.0.1:6379> strlen name
(integer) 7
127.0.0.1:6379> strlen notexistkey
(integer) 0

APPEND

可用版本:>= 2.0.0

时间复杂度:O(1)

在key对应的字符串类型value后面追加数据;

如果key不存在,相当于在空字符后追加。

命令格式如下:

1
APPEND key value

示例:

1
2
3
4
5
6
7
8
9
# 删除key,便于测试
127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> append mykey "hello"
(integer) 5
127.0.0.1:6379> append mykey " world"
(integer) 11
127.0.0.1:6379> get mykey
"hello world"

SETRANGE

可用版本:>= 2.2.0

时间复杂度:O(1)

从指定偏移量offset开始,修改key对应的value值;

如果value长度小于offset,Redis会用空白字符补充中间的数据(value长度为 2 ,但指定的offset是 5 ,那么原字符和偏移量之间的空白将用零字节 \x00 补充);

如果key不存在,value当作空白字符串处理;

由于Redis字符串的大小被限制在 512 兆(megabytes)以内,所以能够使用的最大偏移量为 2^29-1(536870911) ,如果需要使用比这更大的空间的话,可以使用多个key 。

命令格式如下:

1
SETRANGE key offset value

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
127.0.0.1:6379> set key "hello world"
OK

# 从第6个偏移量开始,替换为“redis”
127.0.0.1:6379> setrange key 6 "redis"
(integer) 11
127.0.0.1:6379> get key
"hello redis"

# offset大于旧值长度,使用“\x00”补充
127.0.0.1:6379> setrange notexistkey 3 "hello"
(integer) 8
127.0.0.1:6379> get notexistkey
"\x00\x00\x00hello"
127.0.0.1:6379> 

GETRANGE

可用版本:>= 2.4.0

时间复杂度:O(N),N为返回字符串长度

Redis 2.0版本中,该命令为 SUBSTR

获取key对应value指定位置的子串,由偏移量start和end决定(左右都是闭区间);

负数偏移量表示从字符串的末尾开始计数,-1 表示最后一个字符,-2 表示倒数第二个字符,以此类推;

如果请求中提供的偏移量超出字符串实际长度限制,以实际长度为准。

命令格式如下:

1
GETRANGE key start end

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
127.0.0.1:6379> set mykey "from zero to hero"
OK

127.0.0.1:6379> getrange mykey 0 3
"from"

127.0.0.1:6379> getrange mykey -4 -1
"hero"

# 超出范围的请求
127.0.0.1:6379> getrange mykey 5 100
"zero to hero"

127.0.0.1:6379> getrange mykey 50 100
""

127.0.0.1:6379> getrange mykey -100 -1
"from zero to hero"

INCR

可用版本:>= 1.0.0

时间复杂度:O(1)

将key对应的value值加 1

如果key不存在,先将值初始化为 0,再执行INCR操作。

如果key对应的值不能转为数字,将会报错。

value值限制在 64 位有符号数字以内。

命令格式如下:

1
INCR key

Redis本身没有整形,都是字符串类型,在执行这个操作时,会把字符串类型转为64位有符号整数处理。

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# key不存在时
127.0.0.1:6379> incr age
(integer) 1
127.0.0.1:6379> get age
"1"

# key存在时
127.0.0.1:6379> set myage 18
OK
127.0.0.1:6379> incr myage
(integer) 19
127.0.0.1:6379> get myage
"19"

# value类型错误
127.0.0.1:6379> set name "lifelmy"
OK
127.0.0.1:6379> incr name
(error) ERR value is not an integer or out of range

INCRBY

可用版本:>= 1.0.0

时间复杂度:O(1)

INCR命令类似,INCRBY 将key对应的value值加上一个整数,而不是始终为 1

如果key不存在,先将值初始化为 0,再执行 INCRBY 操作;

如果key对应的值不能转为数字,将会报错;

value值限制在 64 位有符号数字以内。

命令格式如下:

1
INCRBY key increment

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 加上一个正数
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> incrby age 5
(integer) 23
127.0.0.1:6379> get age
"23"

# 加上一个负数,相当于减
127.0.0.1:6379> incrby age -5
(integer) 18
127.0.0.1:6379> get age
"18"

INCRBYFLOAT

可用版本:>= 2.6.0

时间复杂度:O(1)

INCRBY 命令类似,INCRBYFLOAT 将key对应的value值加上一个浮点数(float),如果是负数,相当于减;

如果key不存在,先将值初始化为 0,再执行 INCRBYFLOAT 操作;

value值和给定的增量increment,都可以是指数形式(如 5.0e3),但是执行 INCRBYFLOAT 命令后保存的是始终是浮点数形式(一个数字, 一个可选的小数点和一个任意长度的小数部分),最多保留17位小数;

当以下任意一个条件发生时, 命令返回一个错误:

  • value 值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存);
  • value 值或者给定的增量increment不能转为为双精度浮点数。

命令格式如下:

1
INCRBYFLOAT key increment

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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 -0.2
"10.4"
127.0.0.1:6379> INCRBYFLOAT mykey 2.0e2
"210.39999999999999999"

# 指数
127.0.0.1:6379> set mykey 5.0e3
OK
127.0.0.1:6379> INCRBYFLOAT mykey 2.0e2
"5200"

DECR

可用版本:>= 1.0.0

时间复杂度:O(1)

INCR命令相反,DECR将value值减一;

如果key不存在,先将值初始化为 0,再执行DECR操作;

如果key对应的值不能转为数字,将会报错;

value值限制在 64 位有符号数字以内。

命令格式如下:

1
DECR key

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> set mykey 10
OK
127.0.0.1:6379> DECR mykey
(integer) 9
127.0.0.1:6379> get mykey
"9"

# 超出64位有符号整数的表示范围
127.0.0.1:6379> SET mykey "234293482390480948029348230948"
OK
127.0.0.1:6379> DECR mykey
(error) ERR value is not an integer or out of range

DECRBY

可用版本:>= 1.0.0

时间复杂度:O(1)

INCRBY 相反,DECRBY 将key对应的value值减去一个整数;

如果key不存在,先将值初始化为 0,再执行 DECRBY 操作;

如果value值不能转为数字,将会报错;

value值限制在 64 位有符号数字以内。

命令格式如下:

1
DECRBY key decrement

示例:

1
2
3
4
5
6
7
8
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 -3
(integer) 10

MSET

支持版本:1.0.1

时间复杂度:O(N),N为key个数

SET 命令类似,MSET 可以一次设置一个或多个key-value;

如果key已经存在,新值会覆盖旧值;

MSET是一个原子操作,所有值会被同时设置,不会存在部分key完成设置而部分key未被处理的情况。

命令格式如下:

1
MSET key value [key value ...]

示例:

1
2
3
4
5
6
127.0.0.1:6379> mset key1 "hello" key2 "world"
OK
127.0.0.1:6379> get key1
"hello"
127.0.0.1:6379> get key2
"world"

MSETNX

可用版本:>= 1.0.1

时间复杂度:O(N),N为key个数

与SETNX类似,MSETNX设置一个或多个值;

当所有给定的key都不存在时,才会执行成功,即使有一个key存在,所有的key-value都不会被设置;

MSETNX是一个原子操作,所有值会被同时设置,不会存在部分key完成设置而部分key未被处理的情况。

命令格式如下:

1
MSETNX key value [key value ...]

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
127.0.0.1:6379> MSETNX key1 "hello" key2 "world"
(integer) 1

# 当前key2已经存在,两个key都不会被设置
127.0.0.1:6379> MSETNX key2 "new world" key3 "lifelmy"
(integer) 0
127.0.0.1:6379> get key2
"world"
127.0.0.1:6379> get key3
(nil)

MGET

可用版本:>= 1.0.1

时间复杂度:O(N),N为key个数

与GET命令类似,MGET一次获取1个或多个key的值;

key不存在时返回nil。

命令格式如下:

1
MGET key [key ...]

示例:

1
2
3
4
5
6
127.0.0.1:6379> mset key1 hello key2 world
OK
127.0.0.1:6379> mget key1 key2 key3
1) "hello"
2) "world"
3) (nil)

更多

微信公众号:CodePlayer