二:Redis String(字符串)

1、String 介绍

  • string是redis最基本的类型,一个key对应一个value。一个键最大能存储 512MB。
命令 描述
SET key value 设置指定 key 的值
GET key 获取指定 key 的值。
GETRANGE key start end 返回 key 中字符串值的子字符
GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
GETBIT key offset****对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
MGET key1 [key2..] 获取所有(一个或多个)给定 key 的值。
SETBIT key offset value 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
SETEX key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
SETNX key value 只有在 key 不存在时设置 key 的值。
SETRANGE key offset value 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。
STRLEN key 返回 key 所储存的字符串值的长度。
MSET key value [key value ...] 同时设置一个或多个 key-value 对。
MSETNX key value [key value ...] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
PSETEX key milliseconds value 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。
INCR key 将 key 中储存的数字值增一。
INCRBY key increment 将 key 所储存的值加上给定的增量值(increment) 。
INCRBYFLOAT key increment 将 key 所储存的值加上给定的浮点增量值(increment) 。
DECR key 将 key 中储存的数字值减一。
DECRBY key decrementkey 所储存的值减去给定的减量值(decrement) 。
APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将 指定value 追加到改 key 原来的值(value)的末尾。

2、String 应用场景

  • 常规计数:微博数,粉丝数等。

3、String 操作介绍

1、SET
1、语法
SET key value [EX seconds] [PX milliseconds] [NX|XX]
  • 将字符串值 value 关联到 key 。

  • 如果 key 已经持有其他值, SET 就覆写旧值, 无视类型。

  • 当 SET 命令对一个带有生存时间(TTL)的键进行设置之后, 该键原有的 TTL 将被清除。

2、可选参数
  • EX seconds : 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。
  • PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。
  • NX : 只在键不存在时, 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value 。
  • XX : 只在键已经存在时, 才对键进行设置操作。
  • 因为 SET 命令可以通过参数来实现 SETNX 、 SETEX 以及 PSETEX 命令的效果, 所以 Redis 将来的版本可能会移除并废弃 SETNX 、 SETEX 和 PSETEX 这三个命令。
3、返回值
  • SET 命令只在设置操作成功完成时才返回 OK ; 如果命令使用了 NX 或者 XX 选项, 但是因为条件没达到而造成设置操作未执行, 那么命令将返回空批量回复(NULL Bulk Reply)。
4、代码示例
  • 对不存在的键进行设置:
redis> SET key "value"
OK

redis> GET key
"value"
  • 对已存在的键进行设置:
redis> SET key "new-value"
OK

redis> GET key
"new-value"
  • 使用 EX 选项:
redis> SET key-with-expire-time "hello" EX 10086
OK

redis> GET key-with-expire-time
"hello"

redis> TTL key-with-expire-time
(integer) 10069
  • 使用 PX 选项:
redis> SET key-with-pexpire-time "moto" PX 123321
OK

redis> GET key-with-pexpire-time
"moto"

redis> PTTL key-with-pexpire-time
(integer) 111939
  • 使用 NX 选项:
redis> SET not-exists-key "value" NX
OK      # 键不存在,设置成功

redis> GET not-exists-key
"value"

redis> SET not-exists-key "new-value" NX
(nil)   # 键已经存在,设置失败

redis> GEt not-exists-key
"value" # 维持原值不变
  • 使用 XX 选项:
redis> EXISTS exists-key
(integer) 0

redis> SET exists-key "value" XX
(nil)   # 因为键不存在,设置失败

redis> SET exists-key "value"
OK      # 先给键设置一个值

redis> SET exists-key "new-value" XX
OK      # 设置新值成功

redis> GET exists-key
"new-value"
2、SETNX
1、语法
SETNX key value
  • 只在键 key 不存在的情况下, 将键 key 的值设置为 value

  • 若键 key 已经存在, 则 SETNX 命令不做任何动作。

  • SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。

2、返回值
  • 命令在设置成功时返回 1 , 设置失败时返回 0
3、代码示例
redis> EXISTS job                # job 不存在
(integer) 0

redis> SETNX job "programmer"    # job 设置成功
(integer) 1

redis> SETNX job "code-farmer"   # 尝试覆盖 job ,失败
(integer) 0

redis> GET job                   # 没有被覆盖
"programmer"
3、SETEX
1、语法
SETEX key seconds value
  • 将键 key 的值设置为 value , 并将键 key 的生存时间设置为 seconds 秒钟。

  • 如果键 key 已经存在, 那么 SETEX 命令将覆盖已有的值。

  • SETEX 命令的效果和以下两个命令的效果类似:

SET key value
EXPIRE key seconds  # 设置生存时间
  • SETEX 和这两个命令的不同之处在于 SETEX 是一个原子(atomic)操作, 它可以在同一时间内完成设置值和设置过期时间这两个操作, 因此 SETEX 命令在储存缓存的时候非常实用。
2、返回值
  • 命令在设置成功时返回 OK 。 当 seconds 参数不合法时, 命令将返回一个错误。
3、代码示例
  • 在键 key 不存在的情况下执行 SETEX
redis> SETEX cache_user_id 60 10086
OK

redis> GET cache_user_id  # 值
"10086"

redis> TTL cache_user_id  # 剩余生存时间
(integer) 49
  • key 已经存在, 使用 SETEX 覆盖旧值:
redis> SET cd "timeless"
OK

redis> SETEX cd 3000 "goodbye my love"
OK

redis> GET cd
"goodbye my love"

redis> TTL cd
(integer) 2997
4、PSETEX
1、语法
PSETEX key milliseconds value
  • 这个命令和 SETEX 命令相似, 但它以毫秒为单位设置 key 的生存时间, 而不是像 SETEX 命令那样以秒为单位进行设置。
2、返回值
  • 命令在设置成功时返回 OK
3、代码示例
redis> PSETEX mykey 1000 "Hello"
OK

redis> PTTL mykey
(integer) 999

redis> GET mykey
"Hello"
5、GET
1、语法
GET key
  • 返回与键 key 相关联的字符串值。
2、返回值
  • 如果键 key 不存在, 那么返回特殊值 nil ; 否则, 返回键 key 的值。

  • 如果键 key 的值并非字符串类型, 那么返回一个错误, 因为 GET 命令只能用于字符串值。

3、代码示例
  • 对不存在的键 key 或是字符串类型的键 key 执行 GET 命令:
redis> GET db
(nil)

redis> SET db redis
OK

redis> GET db
"redis"
  • 对不是字符串类型的键 key 执行 GET 命令:
redis> DEL db
(integer) 1

redis> LPUSH db redis mongodb mysql
(integer) 3

redis> GET db
(error) ERR Operation against a key holding the wrong kind of value
6、GETSET
1、语法
GETSET key value
  • 将键 key 的值设为 value , 并返回键 key 在被设置之前的旧值。
2、返回值
  • 返回给定键 key 的旧值。
  • 如果键 key 没有旧值, 也即是说, 键 key 在被设置之前并不存在, 那么命令返回 nil
  • 当键 key 存在但不是字符串类型时, 命令返回一个错误。
3、代码示例
redis> GETSET db mongodb    # 没有旧值,返回 nil
(nil)

redis> GET db
"mongodb"

redis> GETSET db redis      # 返回旧值 mongodb
"mongodb"

redis> GET db
"redis"
7、STRLEN
1、语法
STRLEN key
  • 返回键 key 储存的字符串值的长度。
2、返回值
  • STRLEN 命令返回字符串值的长度。
  • 当键 key 不存在时, 命令返回 0
  • key 储存的不是字符串值时, 返回一个错误。
3、代码示例
  • 获取字符串值的长度:
redis> SET mykey "Hello world"
OK

redis> STRLEN mykey
(integer) 11
  • 不存在的键的长度为 0
redis> STRLEN nonexisting
(integer) 0
8、APPEND
1、语法
APPEND key value
  • 如果键 key 已经存在并且它的值是一个字符串, APPEND 命令将把 value 追加到键 key 现有值的末尾。

  • 如果 key 不存在, APPEND 就简单地将键 key 的值设为 value , 就像执行 SET key value 一样。

2、返回值
  • 追加 value 之后, 键 key 的值的长度。
3、示例代码
  • 对不存在的 key 执行 APPEND
redis> EXISTS myphone               # 确保 myphone 不存在
(integer) 0

redis> APPEND myphone "nokia"       # 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"
(integer) 5                         # 字符长度
  • 对已存在的字符串进行 APPEND
redis> APPEND myphone " - 1110"     # 长度从 5 个字符增加到 12 个字符
(integer) 12

redis> GET myphone
"nokia - 1110"
9、SETRANGE
1、语法
SETRANGE key offset value
  • 从偏移量 offset 开始, 用 value 参数覆写(overwrite)键 key 储存的字符串值。

  • 不存在的键 key 当作空白字符串处理。

SETRANGE 命令会确保字符串足够长以便将 value 设置到指定的偏移量上, 如果键 key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但你设置的 offset10 ), 那么原字符和偏移量之间的空白将用零字节(zerobytes, "\x00" )进行填充。

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

Warning

当生成一个很长的字符串时, Redis 需要分配内存空间, 该操作有时候可能会造成服务器阻塞(block)。 在2010年出产的Macbook Pro上, 设置偏移量为 536870911(512MB 内存分配)将耗费约 300 毫秒, 设置偏移量为 134217728(128MB 内存分配)将耗费约 80 毫秒, 设置偏移量 33554432(32MB 内存分配)将耗费约 30 毫秒, 设置偏移量为 8388608(8MB 内存分配)将耗费约 8 毫秒。

2、返回值
  • SETRANGE 命令会返回被修改之后, 字符串值的长度。
3、代码示例
  • 对非空字符串执行 SETRANGE 命令:
redis> SET greeting "hello world"
OK

redis> SETRANGE greeting 6 "Redis"
(integer) 11

redis> GET greeting
"hello Redis"
  • 对空字符串/不存在的键执行 SETRANGE 命令:
redis> EXISTS empty_string
(integer) 0

redis> SETRANGE empty_string 5 "Redis!"   # 对不存在的 key 使用 SETRANGE
(integer) 11

redis> GET empty_string                   # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
10、GETRANGE
1、语法
GETRANGE key start end
  • 返回键 key 储存的字符串值的指定部分, 字符串的截取范围由 startend 两个偏移量决定 (包括 startend 在内)。

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

  • GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。

  • GETRANGE 命令在 Redis 2.0 之前的版本里面被称为 SUBSTR 命令。

2、返回值
  • GETRANGE 命令会返回字符串值的指定部分。
3、代码示例
redis> SET greeting "hello, my friend"
OK

redis> GETRANGE greeting 0 4          # 返回索引0-4的字符,包括4。
"hello"

redis> GETRANGE greeting -1 -5        # 不支持回绕操作
""

redis> GETRANGE greeting -3 -1        # 负数索引
"end"

redis> GETRANGE greeting 0 -1         # 从第一个到最后一个
"hello, my friend"

redis> GETRANGE greeting 0 1008611    # 值域范围不超过实际字符串,超过部分自动被符略
"hello, my friend"
11、INCR
1、语法
INCR key
  • 为键 key 储存的数字值加上一。

  • 如果键 key 不存在, 那么它的值会先被初始化为 0 , 然后再执行 INCR 命令。

  • 如果键 key 储存的值不能被解释为数字, 那么 INCR 命令将返回一个错误。

  • 本操作的值限制在 64 位(bit)有符号数字表示之内。

  • INCR 命令是一个针对字符串的操作。 因为 Redis 并没有专用的整数类型, 所以键 key 储存的值在执行 INCR 命令时会被解释为十进制 64 位有符号整数。

2、返回值
  • INCR 命令会返回键 key 在执行加一操作之后的值。
3、代码示例
redis> SET page_view 20
OK

redis> INCR page_view
(integer) 21

redis> GET page_view    # 数字值在 Redis 中以字符串的形式保存
"21"
12、INCRBY
1、语法
INCRBY key increment
  • 为键 key 储存的数字值加上增量 increment

  • 如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 INCRBY 命令。

  • 如果键 key 储存的值不能被解释为数字, 那么 INCRBY 命令将返回一个错误。

  • 本操作的值限制在 64 位(bit)有符号数字表示之内。

  • 关于递增(increment) / 递减(decrement)操作的更多信息, 请参见 INCR 命令的文档。

2、返回值
  • 在加上增量 increment 之后, 键 key 当前的值。
3、代码示例
  • 键存在,并且值为数字:
redis> SET rank 50
OK

redis> INCRBY rank 20
(integer) 70

redis> GET rank
"70"
  • 键不存在:
redis> EXISTS counter
(integer) 0

redis> INCRBY counter 30
(integer) 30

redis> GET counter
"30"
  • 键存在,但值无法被解释为数字:
redis> SET book "long long ago..."
OK

redis> INCRBY book 200
(error) ERR value is not an integer or out of range
13、INCRBYFLOAT
1、语法
INCRBYFLOAT key increment
  • 为键 key 储存的值加上浮点数增量 increment

  • 如果键 key 不存在, 那么 INCRBYFLOAT 会先将键 key 的值设为 0 , 然后再执行加法操作。

  • 如果命令执行成功, 那么键 key 的值会被更新为执行加法计算之后的新值, 并且新值会以字符串的形式返回给调用者。

  • 无论是键 key 的值还是增量 increment , 都可以使用像 2.0e73e590e-2 那样的指数符号(exponential notation)来表示, 但是, 执行 INCRBYFLOAT 命令之后的值总是以同样的形式储存, 也即是, 它们总是由一个数字, 一个(可选的)小数点和一个任意长度的小数部分组成(比如 3.1469.768 ,诸如此类), 小数部分尾随的 0 会被移除, 如果可能的话, 命令还会将浮点数转换为整数(比如 3.0 会被保存成 3 )。

  • 此外, 无论加法计算所得的浮点数的实际精度有多长, INCRBYFLOAT 命令的计算结果最多只保留小数点的后十七位。

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

    • key 的值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型);
    • key 当前的值或者给定的增量 increment 不能被解释(parse)为双精度浮点数。
2、返回值
  • 在加上增量 increment 之后, 键 key 的值。
3、代码示例
redis> GET decimal
"3.0"

redis> INCRBYFLOAT decimal 2.56
"5.56"

redis> GET decimal
"5.56"
14、DECR
1、语法
DECR key
  • 为键 key 储存的数字值减去一。
  • 如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 DECR 操作。
  • 如果键 key 储存的值不能被解释为数字, 那么 DECR 命令将返回一个错误。
  • 本操作的值限制在 64 位(bit)有符号数字表示之内。
  • 关于递增(increment) / 递减(decrement)操作的更多信息, 请参见 INCR 命令的文档。
2、返回值
  • DECR 命令会返回键 key 在执行减一操作之后的值。
3、代码示例
  • 对储存数字值的键 key 执行 DECR 命令:
redis> SET failure_times 10
OK

redis> DECR failure_times
(integer) 9
  • 对不存在的键执行 DECR 命令:
redis> EXISTS count
(integer) 0

redis> DECR count
(integer) -1
15、DECRBY
1、语法
DECRBY key decrement
  • 将键 key 储存的整数值减去减量 decrement

  • 如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 DECRBY 命令。

  • 如果键 key 储存的值不能被解释为数字, 那么 DECRBY 命令将返回一个错误。

  • 本操作的值限制在 64 位(bit)有符号数字表示之内。

  • 关于更多递增(increment) / 递减(decrement)操作的更多信息, 请参见 INCR 命令的文档。

2、返回值
  • DECRBY 命令会返回键在执行减法操作之后的值。
3、代码示例
  • 对已经存在的键执行 DECRBY 命令:
redis> SET count 100
OK

redis> DECRBY count 20
(integer) 80
  • 对不存在的键执行 DECRBY 命令:
redis> EXISTS pages
(integer) 0

redis> DECRBY pages 10
(integer) -10
16、MSET
1、语法
MSET key value [key value …]
  • 同时为多个键设置值。
  • 如果某个给定键已经存在, 那么 MSET 将使用新值去覆盖旧值, 如果这不是你所希望的效果, 请考虑使用 MSETNX 命令, 这个命令只会在所有给定键都不存在的情况下进行设置。
  • MSET 是一个原子性(atomic)操作, 所有给定键都会在同一时间内被设置, 不会出现某些键被设置了但是另一些键没有被设置的情况。
2、返回值
  • MSET 命令总是返回 OK
3、代码示例
  • 同时对多个键进行设置:
redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK

redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"
  • 覆盖已有的值:
redis> MGET k1 k2
1) "hello"
2) "world"

redis> MSET k1 "good" k2 "bye"
OK

redis> MGET k1 k2
1) "good"
2) "bye"
17、MSETNX
1、语法
MSETNX key value [key value …]
  • 当且仅当所有给定键都不存在时, 为所有给定键设置值。
  • 即使只有一个给定键已经存在, MSETNX 命令也会拒绝执行对所有键的设置操作。
  • MSETNX 是一个原子性(atomic)操作, 所有给定键要么就全部都被设置, 要么就全部都不设置, 不可能出现第三种状态。
2、返回值
  • 当所有给定键都设置成功时, 命令返回 1 ; 如果因为某个给定键已经存在而导致设置未能成功执行, 那么命令返回 0
3、代码示例
  • 对不存在的键执行 MSETNX 命令:
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1

redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"
  • 对某个已经存在的键进行设置:
redis> MSETNX rmdbs "Sqlite" language "python"  # rmdbs 键已经存在,操作失败
(integer) 0

redis> EXISTS language                          # 因为 MSETNX 命令没有成功执行
(integer) 0                                     # 所以 language 键没有被设置

redis> GET rmdbs                                # rmdbs 键也没有被修改
"MySQL"
18、MGET
1、语法
MGET key [key …]
  • 返回给定的一个或多个字符串键的值。

  • 如果给定的字符串键里面, 有某个键不存在, 那么这个键的值将以特殊值 nil 表示。

2、返回值
  • MGET 命令将返回一个列表, 列表中包含了所有给定键的值。
3、代码示例
redis> SET redis redis.com
OK

redis> SET mongodb mongodb.org
OK

redis> MGET redis mongodb
1) "redis.com"
2) "mongodb.org"

redis> MGET redis mongodb mysql     # 不存在的 mysql 返回 nil
1) "redis.com"
2) "mongodb.org"
3) (nil)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339