哈喽,上节课我们对redis
做了一个简单的介绍,这节课我们开始介绍一下redis
的数据类型。
简介
首先,String
是redis
最基本的数据类型,一个key
对应着一个value
。翻译成中文来说的话就是字符串类型,这个类型也是我们很常用的一种数据类型。
而这个数据类型是二进制安全的,或许这个意思大家不会太明白,其实这就意味着String
类型里面可以包含任何数据,包括图片和视频,因为图片视频是可以序列化成二进制字符串的,那么序列化成了字符串,自然就可以存储进redis
中。但是有一个要注意的是redis
中的String value
最大可以存储512 M
。
String
操作命令
我们对String
类型做了简单的介绍,那么这个数据类型怎么使用呢?上节课中我们举了几个例子,我们都是用命令来操作数据库,而就上节课的例子中,用到的其实都是String
类型,那么我们来看一下String
都有哪些操作命令:
set <key> <value>
这个命令我们也不陌生了,这个命令是往数据库添加键值对,可能有人要问什么是键值对?键值对其实就是key-value
。因为key
翻译过来就有键的意思。那么key-value
便是键值对。
而这个命令通常默认添加到数据库中的数据类型,我们可以看一下:
我们用set
命令新增了两个键值对。然后我们看见两个value
一个是数字,一个是字母和数字的组合。那么我们也很容易看出k2
对应的value
是字符串类型,那么k1
对应的value
又是什么类型呢?我们可以用type
命令来查看一下,输出的也是string
说明k1
对应的value
也是字符串类型。
get <key>
既然有set
命令,那么对应自然有get
命令,这个命令上节课我们也做个简单的介绍,这个命令是获取到指定key
所对应value
:
我们可以看到我们可以通过get <key>
来获取到指定key
的值,而输出的值也都是有引号括起来,可见这都是字符串类型的数据。
append <key> <value>
这个命令我们之前没有见到过,这个命令是什么意思呢?
我们先来考虑一个问题,我们用set
命令可以新增一个键值对,比如我们set k1 100
新增了一个键值对,如果我们再次重新用set
命令来对k1
进行操作会什么样呢?
我们看见这步操作会直接将指定的key
原来的value
完全覆盖掉。
而append
命令则是将指定的value
追加到指定key
原来value
的末尾,并且输出value
字符串总长度:
我们看见,k1
对应的原来value
是 200,然后通过append
将 100 追加到原来value
的末尾,然后输出了一个数字,这个数字便是k1
对应的新的值的长度,然后再用get
命令查看k1
对应的value
发现我们已经将 100 追加到了 200 的末尾。
strlen <key>
这个命令大家应该可以直接猜到,这就是用来查看指定key
对应value
的长度,我们可以看一下效果:
setnx <key> <value>
这个命令我们之前也没有提到过的,这个命令也是用来新增键值对的,但这个命令是有个特殊的特性,因为这个命令在新增之前会检查key
的存在性,只有当key
不存在时才会添加成功:
我们来看一下,现在库里有k1
和k2
这两个key
,那么我们用setnx
命令对k1
重新设置value
,然后输出了一个数字 0,我们上节课也提到过了,这是代表是否成功,既然输出 0,那么说明这次操作是失败的。
然后我们用get
命令来看一下k1
的值,我们发现,并没有被修改,也正是证明了setnx
无法对已存在的key
进行修改操作。那么我们再来看用setnx
新增一个k3
。
输出了 1,说明新增成功,再用get
命令来查看一下k3
的值,输出的正是我们指定的value
incr / decr <key>
这两个命令是缩写,分别对应increment
和decrement
,这两个命令的用处便是让指定key
对应value
值的数字加 1 或者减 1:
我们来看一下k3
原有的value
是 500,然后执行incr
命令,使得k3
的value
加 1,输出的便是修改后的k3
对应的value
。然后执行decr
命令之后也是一样。
而这些命令都是原子操作。那么什么是原子操作呢?所谓原子操作是指不会被线程调度机制打断的操作,一旦开始,就一定会运行到结束。在单线程中能够在单条命令中完成的操作都可以认为是原子操作。而在多线程中不能被其他线程或进程打断的操作都是原子操作。
incrby / decrby <key> <步长>
这两个命令和之前看见的incr / decr
看着很想,当然这两个命令呢也是让指定key
对应value
的数字值加上或者减去指定的值。为啥这里说的是指定值呢?因为我们看见这个命令除了key
之外还有一个所谓“步长”的参数。那么这个步长是什么意思呢?
这个步长就是指我们说的指定的值。我们来看一下是什么效果:
我们来看k3
原来的value
是 500,然后执行incrby
命令,然后将步长设为 50,这就代表了将k3
对应的value
加上 50,然后输出的便是k3
加上步长之后的的值,然后再执行decrby
命令,将步长设为 20,代表将k3
对应的value
减去 20。并输出计算后的值。
mset <key1> <value1> <key2> <value2>...
这个命令可以添加多个键值对,用法和set
命令近似,我们就不再赘述了。
mget <key1> <key2>...
这个命令可以获取多个key
的value
,用法与get
命令近似,我们也就不再赘述了。
msetnx <key1> <value1> <key2> <value2>...
该命令与setnx
命令近似,当所添加的所有key
都不存在时,便添加所有键值对到库里。该命令具有原子性。该命令设置的key
中有一个无法成功添加,整个命令都会失败。
getrange <key> <起始位置> <结束位置>
这个命令可以获取指定key
的value
的某一段值,怎么解释呢?语言从来都是苍白无力的。我们来看一下示例:
我们来看一下,我们执行getrange
命令,传入的起始位置和结束位置分别为 0 和 3。这个 0 和 3 又是什么意思呢?这个就是所谓的索引,计算机中的索引通常都是从 0 开始计数,起始位置为 0,那么就代表从左往右数第 1 位,结束位置为 3,代表从左往右数第 4 位。
整个命令便是获取到k3
对应value
的第 1 位到第 4 位的片段。输出的便是abcd
。
setrange <key> <起始位置> <value>
该命令从指定key
的value
的指定位置开始修改value
值。我们来看一下:
我们执行了setrange
命令,起始位置设置为 3,也就代表从k1
对应value
值的第 4 位开始修改,然后输出的便是修改后的value
的长度。然后执行get
命令,我们看见从第 4 位开始往后便改成了我们指定的value
。
setex <key> <过期时间> <value>
这个命令用于添加键值对,并设置过期时间,我们之前可以利用set
命令新增键值对,然后用expire
命令给key
设置过期时间。但是setex
命令可以直接在新增键值对的时候可以直接设置过期时间。
我们可以从图中看出该命令的用法,然后可以用ttl
命令查看key
的过期时间。
getset <key> <value>
这个命令在给指定key
设置新值的同时获取到该key
原来的值:
我们看见k1
原来的value
是v200
,然后执行getset
命令,输出了k1
对应的原来的value
,那么我们再执行get
命令,发现k1
对应的value
已经被修改了。
以上便是String
类型的常用命令。
String
数据结构
我们介绍了String
类型的常用命令,那么我们来介绍一下String
的数据结构。
String
类型是简单的动态字符串,底层来说内部结构类似于java
的ArrayList
,通过预分配冗余空间来减少内存频繁分配:
我们来看一下底层的内存分配情况,其实每一个字符串再内存中存储时开辟的空间为capacity
,而capacity
是要大于字符串长度的,如果存储字符串继续增长,那么就要对存储空间进行扩容。
如果字符串大小小于1 M
,那么每次扩容将会以capacity
为单位,每次扩容将扩充一个单位。
如果字符串大小大于1 M
,那么每次扩容将只扩充1 M
的空间。
总结
String
类型为redis
最基础的类型String
常用命令:set <key> <value>
get <key>
append <key> <value>
strlen <key>
setnx <key> <value>
incr / decr <key>
incrby / decrby <key> <步长>
mset <key1> <value1> <key2> <value2>...
mget <key1> <key2>...
msetnx <key1> <value1> <key2> <value2>...
getrange <key> <起始位置> <结束位置>
setrange <key> <起始位置> <value>
setex <key> <过期时间> <value>
getset <key> <value>
String
是动态字符串- 通过分配冗余空间减少内存频繁分配
- 字符串会动态对空间进行扩展
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/redis-datatype_string/