Redis数据结构之字符串

  • 字符串
    • 存储结构
  • 命令
    • SET命令
      • 改变覆盖规则
    • GET命令
    • GETSET命令
    • MSET命令
    • MGET命令
    • MSETNX命令
    • STRLEN命令
    • GETRANGE
    • SETRANGE命令
    • APPEND命令
      • 处理不存在的键
  • 存储数字值
    • INCRBY 和 DECRBY命令
      • 类型限制
      • 处理不存在的键
    • INCR 和 DECR 命令
    • INCRBYFLOAT命令
      • 处理不存在的键
      • 执行浮点数减法操作
      • INCRBYFLOAT 与 整数值
      • 小数位的长度限制
      • 精度问题

字符串

字符串(string)键是Redis中最基本的键值对类型,这种类型的键值对会在数据库中把单独的一个键单独的一个值 关联起来,被关联的键和值可以是普通的文字数据,也可以是图片、视频、音频、压缩文件等更为复杂的二进制数据。

存储结构

字符串类型键的存储结构如下图所示:

  • 与键 “message” 相关联的值是 “hello world”
  • 与键 “number” 相关联的值是 “10086”
  • 与键 “homepage” 相关联的值是 “redis.io”
  • 与键 “redis-log.jpg” 相关联的值是 二进制数据

Redis为字符串类型键提供了一系列操作命令,通过这些命令,用户可以:

  • 为字符串键设置值
  • 获取字符串键的值
  • 在获取旧值的同时为字符串键设置新值
  • 同时为多个字符串键设置值,或者同时获取多个字符串键的值
  • 获取字符串值的长度
  • 获取字符串值指定索引范围内的内容,或者对字符串值指定索引范围内的内容进行修改
  • 将一些内容追加到字符串值的末尾
  • 对字符串键存储的整数值或者浮点数值执行加法操作或减法操作

命令

命令 用法及参数 说明
SET SET key value [expiration EX seconds | PX milliseconds] [NX | XX] 为指定的字符串键设置相应的值,NXXX选项用来指示覆盖规则,EXPX用来指定键的过期时间,单位分别为毫秒
GET GET key 获取指定键的值
MSET MSET key value [key value…] 设置多个键值对
MGET MGET key [key …] 获取多个键的值
MSETNX MSETNX key value [key value …] 对多个键设置值,只在给定所有键都不存在时执行设置操作,只要有一个键存在则放弃执行操作
STRLEN STRLEN key 获取指定字符串键的值的字节长度
GETRANGE GETRANGE key start end 获取指定键的值的字符串索引区间的内容,从start 到end直接的所有内容
SETRANGE SETRANGE key index substitute 将字符串键的值从索引 index 开始的部分替换为指定的内容
APPEND APPEND key suffix 为给定键的值追加内容
INCRBY INCRBY key increment 适用于字符串键值为整数时,针对值执行加法操作
DECRBY DECRBY key decrement 适用于字符串键值为整数时,针对值执行减法操作
INCR INCR key 指定键的值加1,等价于 INCRBY key 1
DECR DECR key 指定键的值减1,等价于 DECRBY key 1
INCRBYFLOAT INCRBYFLOAT key increment 字符串键的浮点数值执行加法运算

SET命令

SET 命令可以为指定的字符串键设置相应的值,在最基本的情况下,只需要向SET命令提供一个键和一个值即可:

SET key value

SET命令在成功后会返回OK作为结果

改变覆盖规则

在默认情况下,对一个已经设置了值的字符串键执行SET命令将导致键的旧值被新值覆盖,如下所示:

127.0.0.1:6379> SET msg "hello world"
OK
127.0.0.1:6379> SET msg "hello redis"
OK

在第二条命令执行完毕后,msg键的值将从原来的 “hello world” 变为 “hello redis”。

从Redis 2.6.12版本开始,用户可以通过向SET命令提供可选的 NX 选项或者 XX 选项来指示SET命令是否覆盖一个已经存在的值:

SET key value [NX | XX]
  • NX:指示SET命令只会在键没有值的情况下执行设置操作,并返回OK表示成功;如果键已经存在,那么SET命令将放弃执行设置操作,并返回控制 nil 表示设置失败。
127.0.0.1:6379> SET password "123456" NX
OK   -- 对尚未有值的password键进行设置,成功
127.0.0.1:6379> SET password "999999" NX
(nil)  -- password键已经有值,设置失败
  • XX:指示SET命令只会在键已经有值的情况下执行设置操作,并返回OK表示成功;如果给定的键并没有值,那么SET命令将放弃设置操作,并返回 nil 表示设置失败。
127.0.0.1:6379> SET homepage "redis.io" XX
(nil)  -- homepage键没有值,设置失败
127.0.0.1:6379> SET homepage "redis.io"
OK  -- 为homepage键设置一个值
127.0.0.1:6379> SET homepage "baidu.com"  XX
OK  -- homepage键有值,设置成功

GET命令

使用GET命令,可以从数据库中获取指定字符串键的值:

GET key

给出指定的键即可返回对应的值,如果键的值不存在,则返回空 (nil)

GETSET命令

GETSET命令就像是GET命令和SET命令的组合版本,GETSET首先获取字符串键目前已有的值,接着为键设置新值,最后把之前获取的旧值返回给用户:

GETSET key new_value
127.0.0.1:6379> GET number  -- number键现在的值为 "123456"
"123456"
127.0.0.1:6379> GETSET number "10086"
"123456"   -- 返回旧值
127.0.0.1:6379> GET number  -- number键的值已被更新为 "10086"
"10086"

MSET命令

除了SET命令和GETSET命令外,Redis还提供了MSET 命令用于对字符串键进行设置。与SET命令和GESET命令只能对单个字符串键设置不同,MSET命令可以一次为多个字符串键设置值:

MSET key value [key value ...]
127.0.0.1:6379> MSET msg "hello world" number "123456"
OK
127.0.0.1:6379> GET msg
"hello world"
127.0.0.1:6379> GET number
"123456"

如果给定的键已存在,那么MSET命令会直接覆盖原来的值

MGET命令

MGET命令就是一个多键版本的GET命令,MGET接受一个或多个字符串键作为参数,并返回这些字符串键的值:

MGET key [key ...]
127.0.0.1:6379> MGET msg number
1) "hello world"
2) "123456"

当指定的键不存在时,返回空值 (nil)

MSETNX命令

MSETNX命令与MSET一样,都可以对多个字符串键设置值:

MSETNX key value [key value ...]

MSETNXMSET的主要区别在于:MSETNX命令只会在所有给定键都不存在的情况下对键进行设置,而不会像MSET那样直接覆盖原值;如果给定的键中,即使只有一个键存在,那么MSETNX命令也会放弃对所有给定键的设置操作。MSETNX命令成功时返回1,失败时返回0。

127.0.0.1:6379> MGET k1 k2 k3 k4
1) (nil)   -- 键k1、k2和k3都不存在
2) (nil)
3) (nil)
4) "hello world"  -- 键k4已存在
127.0.0.1:6379> MSETNX k1 "one" k2 "two" k3 "three" k4 "four"
(integer) 0  -- 因为键k4已存在,所以MSETNX未能执行设置操作
127.0.0.1:6379> MGET k1 k2 k3 k4
1) (nil)
2) (nil)
3) (nil)
4) "hello world"

STRLEN命令

STRLEN命令可以用来获取指定字符串键存储值的字节长度:

STRLEN  key
127.0.0.1:6379> GET number
"12345"
127.0.0.1:6379> STRLEN number
(integer) 5

版本要求:STRLEN命令从Redis 2.2.0开始可用

GETRANGE

通过使用GETRANGE命令,可以获取字符串值从 start 索引开始,直到 end 索引为止的所有内容:

GETRANGE key start end
127.0.0.1:6379> SET msg "hello world"
OK
127.0.0.1:6379> GETRANGE msg 0 4
"hello"
127.0.0.1:6379> GETRANGE msg 6 10
"world"

GETRANGE命令的索引支持正向和反向两种方式:

  • 正向索引:类似于数组的下标一样,从左到右依次为 0、1、2 … n
  • 反向索引:从右到左,起始值为 -1 、-2 … -n

版本要求:GETRANGE命令从Redis 2.4.0开始可用。

SETRANGE命令

通过SETRANGE命令,用户可以将字符串键的值从索引 index 开始的部分替换为指定的新内容,被替换内容的长度取决于新内容的长度:

SETRANGE  key  index  substitute

SETRANGE命令执行成功后,会返回字符串值当前的长度作为结果。

127.0.0.1:6379> GET msg
"hello world"
127.0.0.1:6379> SETRANGE msg 6 "redis"
(integer) 11
127.0.0.1:6379> GET msg
"hello redis"

SETRANGE命令扩展字符串,规则如下:

  • 根据新内自动扩展字符串键的值,以适应新内容。
  • 根据给定的 index 索引扩展字符串,当给定的索引 index 超出字符串值的长度时,字符串值末尾直到索引 index - 1之间的部分将用空字节进行填充,这些字节的所有二进制位都会被设置为 0。
127.0.0.1:6379> GET msg
"hello"
127.0.0.1:6379> STRLEN msg
(integer) 5  -- 当前字符串值的字节长度为5
127.0.0.1:6379> SETRANGE msg 10 "world"  -- 指定在索引 10 的位置处开始设置 world子串
(integer) 15
127.0.0.1:6379> GET msg
"hello\x00\x00\x00\x00\x00world"
  1. 先将原字符串值 “hello” 的长度扩展至15个字节长度;
  2. 然后将原字符串 "hello"末尾直到索引 9之间的所有字节都填充为空字节;
  3. 最后再降索引10到索引14之间的内容设置为 “world”。

上面的步骤如下图所示:

复杂度: O ( N ) O(N) O(N),其中N为被修改内容的长度。
版本要求:SETRANGE命令从Redis 2.2.0开始可用。

APPEND命令

通过调用APPEND命令,用户可以将给定的内容追加到字符串键已有的值的末尾:

APPEND key suffix

APPEND命令在执行追加操作之后,会返回字符串值当前的长度作为命令的返回值。

127.0.0.1:6379> GET msg
"hello"
127.0.0.1:6379> APPEND msg " world"
(integer) 11

处理不存在的键

如果用户给定的键不存在,那么APPEND命令会先将键的值初始化为空字符串 “”,然后再执行追加操作,如下所示:

127.0.0.1:6379> GET name
(nil)
127.0.0.1:6379> APPEND name "admin"
(integer) 5
127.0.0.1:6379> GET name
"admin"

复杂度: O ( N ) O(N) O(N),其中N为新追加的内容的长度
版本要求:APPEND命令从Redis 2.0.0开始可用

存储数字值

每当用户将一个值存储到字符串键里面的时候,Redis都会对这个值进行检测,如果这个值能够被解释为以下两种类型的其中一种,那么Redis就会把这个值当做数字来处理:

  • 能够使用C语言的 long long int 类型存储的整数;
  • 能够使用C语言的 long double类型存储的浮点数。

以下是不同类型的值,并说明了Redis对他们的解释方式:

INCRBY 和 DECRBY命令

当字符串键存储的值能够被Redis解释为整数时,用户就可以通过 INCRBY命令和DECRBY命令对被存储的整数值执行加法或减法操作。

INCRBY key increment  -- 加法操作
DECRBY key decrement  -- 减法操作
127.0.0.1:6379> SET number 100
OK
127.0.0.1:6379> GET number
"100"
127.0.0.1:6379> INCRBY number 300
(integer) 400
127.0.0.1:6379> INCRBY number 25
(integer) 425
127.0.0.1:6379> GET number
"425"
127.0.0.1:6379> DECRBY number 25
(integer) 400

类型限制

当字符串键的值不能被Redis解释为整数时,对键执行INCRBY命令或 DECRBY命令将返回一个错误:

127.0.0.1:6379> SET pi 3.14
OK
127.0.0.1:6379> INCRBY pi 100  --不能对浮点数执行INCRBY命令
(error) ERR value is not an integer or out of range
127.0.0.1:6379> SET msg "hello world"
OK
127.0.0.1:6379> INCRBY msg   -- 不能对字符串执行INCRBY命令
(error) ERR wrong number of arguments for 'incrby' command
127.0.0.1:6379> SET big-number   11111111111111111111111111111111111111111111
OK
127.0.0.1:6379> INCRBY big-number    -- 不能对超过64位长度的整数执行INCRBY
(error) ERR value is not an integer or our of range

处理不存在的键

INCRBY命令或DECRBY命令遇到不存在的键时,命令会先将键的值初始化为0,然后再执行相应的加法或减法操作:

127.0.0.1:6379> GET x
(nil)
127.0.0.1:6379> INCRBY x 100   -- 先将键的值初始化为0,然后再执行
(integer) 100
127.0.0.1:6379> GET x
"100"

复杂度: O ( 1 ) O(1) O(1)
版本要求:INCRBY命令和DECRBY命令从Redis 1.0.0开始可用。

INCR 和 DECR 命令

因为对整数执行加 1 或减 1的操作场景经常出现,所以Redis提供了 INCR命令和DECR命令来简化加法和减法操作:

INCR key  等价于 INCRBY key 1  -- 执行加一操作
DECR key 等价于 DECRBY key 1  -- 执行减一操作
127.0.0.1:6379> SET counter 100
OK
127.0.0.1:6379> INCR counter
(integer) 101
127.0.0.1:6379> DECR counter
(integer) 100

复杂度: O ( 1 ) O(1) O(1)
版本要求:INCR命令和DECR命令从Redis 1.0.0开始可用。

INCRBYFLOAT命令

除了用于执行整数的加法操作 INCR命令和INCRBY命令外,Redis还提供了用于执行浮点数的加法操作的 INCRBYFLOAT命令:

INCRBYFLOAT  key increment

INCRBYFLOAT命令可以把一个浮点数增量加到字符串键存储的数字值上面,并返回键在执行加法后的数字值作为结果。

127.0.0.1:6379> SET price 10.14
OK
127.0.0.1:6379> INCRBYFLOAT price 2.55
"12.6899999999999995"

处理不存在的键

INCR命令或INCRBY命令一样,当INCRBYFLOAT命令遇到键不存在时,会先将键的值初始化为0,然后再执行操作。

执行浮点数减法操作

Redis为INCR命令或INCRBY命令都提供了对应的减法命令,如 DECR命令和DECRBY命令,但是并没有为 INCRBYFLOAT命令提供相应的减法操作命令,因此用户只能通过给INCRBYFLOAT命令传入负数的增量来执行减法操作。

INCRBYFLOAT 与 整数值

INCRBYFLOAT命令对于类型限制的要求比INCRBY命令和INCR命令要宽松得多:

  • INCRBYFLOAT命令既可以用于浮点数值,也可以用于整数值
  • INCRBYFLOAT命令的增量既可以是浮点数,也可以是整数
  • INCRBYFLOAT命令的执行结果可以表示为整数时,命令的执行结果将以整数形式存储
127.0.0.1:6379> SET pi 1
OK
127.0.0.1:6379> GET pi
"1"
127.0.0.1:6379> INCRBYFLOAT pi 2.14
"3.14"
127.0.0.1:6379> INCRBYFLOAT pi 0.86
"4"

小数位的长度限制

虽然Redis并不限制字符串键存储的浮点数的小数位长度,但是使用 INCRBYFLOAT命令处理浮点数的时候,命令最多只会保留计算结果小数点后的17位数字,超过这个范围的小数将被截断。

精度问题

在上面第一个例子中,我们看到 INCRBYFLOAT命令在处理浮点数计算的时候,会有精度不准确的问题,针对这个问题,目前Redis没有处理方案,因此,我们在确定业务需要的情况下,尽可能的通过乘以倍数的方式,将浮点数升级为整数形式,然后使用 INCR系列命令进行计算

复杂度: O ( 1 ) O(1) O(1)
版本要求:INCRBYFLOAT命令从Redis 2.6.0开始可用。

下一篇:Redis学习手册2—数据结构之散列

Redis学习手册1—数据结构之字符串相关推荐

  1. 转-Redis学习手册(目录)

    为什么自己当初要选择Redis作为数据存储解决方案中的一员呢?现在能想到的原因主要有三.其一,Redis不仅性能高效,而且完全免费.其二,是基于C/C++开发的服务器,这里应该有一定的感情因素吧.最后 ...

  2. Redis学习笔记【04】 - 字符串

    一.简介 字符串类型是redis最基础的数据结构.首先键都是字符串类型,而其它几种数据结构类型都是在字符串类型基础上构建的,所以字符串类型能为其他四种数据结构的学习奠定基础. 字符串类型的值实际可以是 ...

  3. Redis学习手册(List数据类型)(转)

    一.概述: 在Redis中,List类型是按照插入顺序排序的字符串链表.和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的 元素.在插入时,如果该键并不存在,Redi ...

  4. Redis学习手册(Sorted-Sets数据类型)

    一.概述: Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中.它们之间的主要差别是Sorted-Sets中的每一个成员都会有一个分数(score ...

  5. Redis学习手册(实例代码)

    在之前的博客中已经非常详细的介绍了Redis的各种操作命令.运行机制和服务器初始化参数配置.本篇博客是该系列博客中的最后一篇,在这里将给出基于Redis客户端组件访问并操作Redis服务器的代码示例. ...

  6. Redis学习手册(String数据类型)

    2019独角兽企业重金招聘Python工程师标准>>> 一.概述: 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的 ...

  7. Redis学习手册(事务)

    一.概述: 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基石.相信对有关系型数据 ...

  8. Redis笔记之基本数据结构 动态字符串SDS

    简单动态字符串 传统上的C语言的字符串表示是以空字符结尾的字符数组(C字符串),redis自己实现一个动态字符串(SDS),两者之间的区别以及使用SDS的好处有: 结构不同.C字符串以空字符结尾的字符 ...

  9. 深入剖析Redis系列(五) - Redis数据结构之字符串

    前言 字符串类型 是 Redis 最基础的数据结构.字符串类型 的值实际可以是 字符串(简单 和 复杂 的字符串,例如 JSON.XML).数字(整数.浮点数),甚至是 二进制(图片.音频.视频),但 ...

最新文章

  1. 《Nature》上给青年科研工作者的几条忠告 (转载)
  2. 15.4.3 用于Generator的泛型方法
  3. (三十)java多线程一
  4. java long double精度丢失_long long类型转double类型部分精度丢失问题
  5. “约见”面试官系列之常见面试题之第七十九篇之ES5和ES6(建议收藏)
  6. html奇淫技巧 2 教你如何进行图文环绕布局 原创
  7. 外设驱动库开发笔记4:AD9833函数发生器驱动
  8. C语言-01基础语法
  9. 使你的MFC程序具有win7的透明立体风格
  10. 背景图片平铺(HTML、CSS)
  11. java list 超出范围_java.sql.SQLException参数索引超出范围(1参数个数,即0)
  12. 淘宝全屏雪花特效页面
  13. matlab z变换离散化_Matlab基础教程
  14. Win10任务栏的隐藏图标的小三角怎么弄出来
  15. Android实现选择相册图片---类似微信的选择图片页面
  16. 应对Apple Music断续费后歌单被删除的一个解决方案
  17. 九度笔记之 1364:v字仇杀队
  18. hdu1754(线段树单点更新)
  19. 传奇GOM引擎单机架设图文教程
  20. [小知識] 判斷是否為繁體字(Big5)

热门文章

  1. 红外线发射与接收电路图
  2. Linux Vim查找字符串
  3. 前端:运用vue.js实现跑马灯效果
  4. 【数据结构】二叉树的概念 | 满二叉树和完全二叉树 | 二叉树的基本性质
  5. WPS文字怎么添加索引和目录
  6. android字体有些显示不正常显示,为什么iconfont字体图标在安卓机上显示不出来
  7. 客户体验:适当摩擦的交互体验
  8. wps - 使用宏来为每行标记序号
  9. 关于Ramos的一些笔记
  10. raid卷的作用_raid卷构建实操(raid0、raid1、raid5、raid6以及raid10),可跟做