Redis第二关入门

第二关入门

2.1 热身

在介绍Redis的数据类型之前,我们先来了解几个比较基础的命令作为热身,赶快打开redis-cli,跟着样例亲自输入命令来体验一下吧!

1.获得符合规则的键名列表
在这里插入图片描述
pattern支持glob风格通配符格式,具体规则如图所示。
在这里插入图片描述
现在Redis中空空如也(如果你从第1关开始就一直跟着敲命令,此时数据库中可能还会有个foo键)。
为了演示KEYS命令,首先我们得给Redis加点料。使用SET命令建立一个名为bar的键:

127.0.0.1:6379> SET bar 1
OK
127.0.0.1:6379> KEYS *
1) "bar"
2) "foo"

注意KEYS命令需要遍历Redis中的所有键,当键的数量较多时会影响性能,不建议在生产环境中使用。
提示 Redis不区分命令大小写。

2.判断一个键是否存在
在这里插入图片描述
如果键存在则返回整数类型1,否则返回0。如:

127.0.0.1:6379> EXISTS bar
(integer) 1

3.删除键
在这里插入图片描述
可以删除一个或多个键,返回值是删除的键的个数。如:

127.0.0.1:6379> DEL bar
(integer) 1
127.0.0.1:6379> DEL bar
(integer) 0

第二次执行DEL命令时因为bar键已经被删除了,实际上并没有删除任何键,所以返回0。

技巧
DEL命令的参数不支持通配符,但我们可以结合Linux的管道和xargs命令自己实现删除所有符合规则的键。比如要删除所有以“user:”开头的键,就可以执行redis-cliKEYS “user:*” | xargs redis-cli DEL。另外由于DEL命令支持多个键作为参数,所以还可以执行redis-cli DEL 'redis-cli KEYS"user:*"'来达到同样的效果,但是性能更好。

4.获得键值的数据类型
在这里插入图片描述
TYPE命令用来获得键值的数据类型,返回值可能是string(字符串类型)、hash(散列类型)、list(列表类型)、set(集合类型)、zset(有序集合类型)。例如:

127.0.0.1:6379> set foo 1
OK
127.0.0.1:6379> type foo
string
127.0.0.1:6379> lpush bar 1
(integer) 1
127.0.0.1:6379> type bar
list

LPUSH命令的作用是向指定的列表类型键中增加一个元素,如果键不存在则创建它。在第三关会详解。

2.2 字符串类型

命令:

	set key value
	get key
	mset k1 v1 k2 v2 ...
	mget k1 k2 ...
	setex key exp value
	incrby key increment

案例:
1.赋值与取值
SET和GET是Redis中最简单的两个命令,它们实现的功能和编程语言中的读写变量相似,如key= "hello"在Redis中是这样表示的:

127.0.0.1:6379> set key hello
OK
#想要读取键值则更简单:
127.0.0.1:6379> get key
"hello"

当键不存在时会返回空结果。

2.递增数字
前面说过字符串类型可以存储任何形式的字符串,当存储的字符串是整数形式时,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值,用法为:

127.0.0.1:6379> incr num
(integer) 1
127.0.0.1:6379> incr num
(integer) 2

当要操作的键不存在时会默认键值为0,所以第一次递增后的结果是1。
当键值不是整数时Redis会提示错误:

127.0.0.1:6379> set foo lorem
OK
127.0.0.1:6379> incr foo
(error) ERR value is not an integer or out of range

3.增加指定的整数
INCRBY命令与INCR命令基本一样,只不过前者可以通过increment参数指定一次增加的数值,如:

127.0.0.1:6379> INCRBY bat 2  
(integer) 2
127.0.0.1:6379> INCRBY bat 3   
(integer) 5

4.减少指定的整数
DECR命令与INCR命令用法相同,只不过是让键值递减,例如:

127.0.0.1:6379> DECR bat
(integer) 4
127.0.0.1:6379> decr bat
(integer) 3

DECRBY key 3相当于INCRBY key -3。

127.0.0.1:6379> decrby bat 3
(integer) 0

#反着用
127.0.0.1:6379> decrby bat -3
(integer) 3
127.0.0.1:6379> incrby bat -3
(integer) 0

5.增加指定浮点数
语法:
在这里插入图片描述
INCRBYFLOAT命令类似INCRBY命令,差别是前者可以递增一个双精度浮点数,如:

127.0.0.1:6379> incrbyfloat bat 2.3
"2.3"
127.0.0.1:6379> incrbyfloat bat 5e+4
"50002.300000000003"

6.向尾部追加值
语法:
在这里插入图片描述
APPEND作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,即相当于SET key value。返回值是追加后字符串的总长度。例如:

127.0.0.1:6379> set key hello
OK
127.0.0.1:6379> append key "worldᆪᄀ"
(integer) 12
127.0.0.1:6379> append key "123"
(integer) 15
127.0.0.1:6379> get key
"helloworld\xa3\xa1123"

7.获取字符串长度
语法:
在这里插入图片描述

127.0.0.1:6379> set key nihao #有几个长度就是几
OK
127.0.0.1:6379> strlen key
(integer) 5

一个汉字长度是3。

8.同时获得/设置多个键值
语法:
在这里插入图片描述
MGET/MSET与GET/SET相似,不过MGET/MSET可以同时获得/设置多个键的键值。例如:

127.0.0.1:6379> mset key1 v1 key2 v2 key3 v3
OK
127.0.0.1:6379> get key2
"v2"
127.0.0.1:6379> mget key1 key3
1) "v1"
2) "v3"

9.Redis Setex 命令为指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值。
语法:

redis 127.0.0.1:6379> SETEX KEY_NAME TIMEOUT VALUE

案例:

127.0.0.1:6379> setex mykey 60 redis
OK
127.0.0.1:6379> ttl mykey
(integer) 55
127.0.0.1:6379> get mykey
"redis"
127.0.0.1:6379> ttl mykey
(integer) 27
127.0.0.1:6379> ttl mykey
(integer) 17
#稍等片刻
127.0.0.1:6379>
127.0.0.1:6379> ttl mykey
(integer) -2
127.0.0.1:6379> ttl mykey
(integer) -2
127.0.0.1:6379> ttl mykey
(integer) -2
127.0.0.1:6379> get mykey	#超过了有效期就会清空键的值。
(nil)

2.3 散列类型

散列类型(hash)的键值也是一种字典结构,其存储了字段(field)和字段值的映射,但字段值只能是字符串,不支持其他数据类型,换句话说,散列类型不能嵌套其他的数据类型。一个散列类型键可以包含至多2的32次方-1个字段。

除了散列类型,Redis的其他数据类型同样不支持数据类型嵌套。比如集合类型的每个元素都只能是字符串,不能是另一个集合或散列表等。

散列类型适合存储对象:使用对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。例如要存储ID为2的汽车对象,可以分别使用名为color、name和price的3个字段来存储该辆汽车的颜色、名称和价格。存储结构如图所示。
在这里插入图片描述
回想在关系数据库中如果要存储汽车对象,存储结构如表所示。
在这里插入图片描述
数据是以二维表的形式存储的,这就要求所有的记录都拥有同样的属性,无法单独为某条记录增减属性。如果想为ID为1的汽车增加生产日期属性,就需要把数据表更改为如表所示的结构。
在这里插入图片描述
对于ID为2和3的两条记录而言date字段是冗余的。可想而知当不同的记录需要不同的属性时,表的字段数量会越来越多以至于难以维护。而且当使用ORM[插图]将关系数据库中的对象实体映射成程序中的实体时,修改表的结构往往意味着要中断服务(重启网站程序)。为了防止这些问题,在关系数据库中存储这种半结构化数据还需要额外的表才行。而Redis的散列类型则不存在这个问题。虽然我们在图中描述了汽车对象的存储结构,但是这个结构只是人为的约定,Redis并不要求每个键都依据此结构存储,我们完全可以自由地为任何键增减字段而不影响其他键。

1.赋值与取值
语法:
在这里插入图片描述
HSET命令用来给字段赋值,而HGET命令用来获得字段的值。用法如下:

127.0.0.1:6379> hset car price 500
(integer) 1
127.0.0.1:6379> hset car name bmw
(integer) 1
127.0.0.1:6379> hget car name
"bmw"

HSET命令的方便之处在于不区分插入和更新操作,这意味着修改数据时不用事先判断字段是否存在来决定要执行的是插入操作(update)还是更新操作(insert)。当执行的是插入操作时(即之前字段不存在)HSET命令会返回1,当执行的是更新操作时(即之前字段已经存在)HSET命令会返回0。更进一步,当键本身不存在时,HSET命令还会自动建立它。

在Redis中每个键都属于一个明确的数据类型,如通过HSET命令建立的键是散列类型,通过SET命令建立的键是字符串类型等。使用一种数据类型的命令操作另一种数据类型的键会提示错误:“ERR Operation against a key holding the wrong kind ofvalue”

当需要同时设置多个字段的值时,可以使用HMSET命令。例如,下面两条语句:
在这里插入图片描述
可以用HMSET命令改写成:
在这里插入图片描述
相应地,HMGET命令可以同时获得多个字段的值:

127.0.0.1:6379> hmget car price name
1) "500"
2) "bmw"

如果想获取键中所有字段和字段值却不知道键中有哪些字段时,应该使用HGETALL命令。如:

127.0.0.1:6379> hgetall car
1) "price"
2) "500"
3) "name"
4) "bmw"

2.判断字段是否存在
在这里插入图片描述
HEXISTS命令用来判断一个字段是否存在。如果存在则返回1,否则返回0(如果键不存在也会返回0)。

127.0.0.1:6379> hexists car model	#判断结果不存在
(integer) 0
127.0.0.1:6379> hset car model c200	#设置字段的值为1
(integer) 1
127.0.0.1:6379> hexists car model	#判断结果存在
(integer) 1

3.当字段不存在时赋值
在这里插入图片描述

4.增加数字
在这里插入图片描述
字符串类型的命令INCRBY,HINCRBY命令与之类似,可以使字段值增加指定的整数。散列类型没有HINCR命令,但是可以通过HINCRBY key field 1来实现。

HINCRBY命令的示例如下:

127.0.0.1:6379> hincrby person score 60
(integer) 60

之前person键不存在,HINCRBY命令会自动建立该键并默认score字段在执行命令前的值为“0”。命令的返回值是增值后的字段值

5.删除字段
在这里插入图片描述
HDEL命令可以删除一个或多个字段,返回值是被删除的字段个数:

127.0.0.1:6379> hdel car price
(integer) 1
127.0.0.1:6379> hdel car price
(integer) 0

2.4 列表类型

1.向列表两端增加元素
在这里插入图片描述
LPUSH命令用来向列表左边增加元素,返回值表示增加元素后列表的长度。

127.0.0.1:6379> lpush numbers 1
(integer) 1

这时numbers键中的数据如图所示。
在这里插入图片描述
LPUSH命令还支持同时增加多个元素,例如:

127.0.0.1:6379> lpush numbers 2 3
(integer) 3

LPUSH会先向列表左边加入"2",然后再加入"3",所以此时numbers键中的数据如图所示。
在这里插入图片描述

向列表右边增加元素的话则使用RPUSH命令,其用法和LPUSH命令一样:

127.0.0.1:6379> rpush numbers 0-1
(integer) 4							#[3,2,1,0]

2.从列表两端弹出元素
在这里插入图片描述
有进有出,LPOP命令可以从列表左边弹出一个元素。LPOP命令执行两步操作:第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。例如,从numbers列表左边弹出一个元素(也就是"3"):

127.0.0.1:6379> lpop numbers
"3"

此时numbers键中的数据如图所示。

127.0.0.1:6379> rpop numbers
"-1"

在这里插入图片描述
结合上面提到的4个命令可以使用列表类型来模拟栈和队列的操作:如果想把列表当做栈,则搭配使用LPUSH和LPOP或RPUSH和RPOP,如果想当成队列,则搭配使用LPUSH和RPOP或RPUSH和LPOP。

3.获取列表中元素的个数
在这里插入图片描述
当键不存在时LLEN会返回0:

127.0.0.1:6379>  rpop numbers
"0"
127.0.0.1:6379>  rpop numbers
"1"
127.0.0.1:6379> llen numbers
(integer) 1

4.获得列表片段
在这里插入图片描述
LRANGE命令是列表类型最常用的命令之一,它能够获得列表中的某一片段。LRANGE命令将返回索引从start到stop之间的所有元素(包含两端的元素)。与大多数人的直觉相同,Redis的列表起始索引为0:

127.0.0.1:6379> lrange numbers 0 2
1) "2"

LRANGE命令也支持负索引,表示从右边开始计算序数,如"-1"表示最右边第一个元素,"-2"表示最右边第二个元素,依次类推:

127.0.0.1:6379> lrange numbers -2 -1
1) "2"	#此时列表是[2]

显然,LRANGE numbers 0 -1可以获取列表中的所有元素。另外一些特殊情况如下。
(1)如果start的索引位置比stop的索引位置靠后,则会返回空列表。

127.0.0.1:6379> lrange numbers 11 111
(empty list or set)

(2)如果stop大于实际的索引范围,则会返回到列表最右边的元素:

127.0.0.1:6379> lrange numbers 0 22
1) "2"	#此时列表是[2]

5.删除列表中指定的值
在这里插入图片描述
LREM命令会删除列表中前count个值为value的元素,返回值是实际删除的元素个数。根据count值的不同,LREM命令的执行方式会略有差异:
● 当count > 0时LREM命令会从列表左边开始删除前 count个值为 value的元素;
● 当count < 0时LREM命令会从列表右边开始删除前|count|个值为value的元素;
● 当count = 0是LREM命令会删除所有值为value的元素。
例如:

127.0.0.1:6379> rpush numbers 2
(integer) 2
127.0.0.1:6379> lrange numbers 0 -1
1) "2"
2) "2"	#请注意这是两个 “2”,后面操作会删掉一个“2”

#从右边开始删除第一个值是“2”的元素
127.0.0.1:6379> lrem numbers -1 2
(integer) 1
127.0.0.1:6379> lrange numbers 0 -1
1) "2"	#删掉了一个“2

2.5 集合类型

1.增加/删除元素
在这里插入图片描述
SADD命令用来向集合中增加一个或多个元素,如果键不存在则会自动创建。因为在一个集合中不能有相同的元素,所以如果要加入的元素已经存在于集合中就会忽略这个元素。本命令的返回值是成功加入的元素数量(忽略的元素不计算在内)。例如:

127.0.0.1:6379> sadd jihe a
(integer) 1
127.0.0.1:6379> sadd jihe a b c
(integer) 2

第二条SADD命令的返回值为2是因为元素“a”已经存在,所以实际上只加入了两个元素。SREM命令用来从集合中删除一个或多个元素,并返回删除成功的个数,例如:

127.0.0.1:6379> srem jihe c d
(integer) 1

由于元素“d”在集合中不存在,所以只删除了一个元素,返回值为1。

2.获得集合中的所有元素
在这里插入图片描述
SMEMBERS命令会返回集合中的所有元素,例如:

127.0.0.1:6379> smembers jihe
1) "b"
2) "a"

3.判断元素是否在集合中
在这里插入图片描述
判断一个元素是否在集合中是一个时间复杂度为O(1)的操作,无论集合中有多少个元素,SISMEMBER命令始终可以极快地返回结果。当值存在时SISMEMBER命令返回1,当值不存在或键不存在时返回0,例如:

127.0.0.1:6379> sismember jihe a
(integer) 1
127.0.0.1:6379> sismember jihe d
(integer) 0

4.集合间运算
在这里插入图片描述
接下来要介绍的3个命令都是用来进行多个集合间运算的。
(1)SDIFF命令用来对多个集合执行差集运算。集合A与集合B的差集表示为A-B,代表所有属于A且不属于B的元素构成的集合(如图所示),即A-B = {x| x∈A且x∈/ B}。例如:
在这里插入图片描述
在这里插入图片描述
SDIFF命令的使用方法如下:

127.0.0.1:6379> sadd setA 1 2 3
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
127.0.0.1:6379> sdiff setA setB
1) "1"
127.0.0.1:6379> sdiff setB set A
1) "4"

SDIFF命令支持同时传入多个键,例如:

127.0.0.1:6379> sadd setC 2 3
(integer) 2
127.0.0.1:6379> sdiff setA setB setC
1) "1"

计算顺序是先计算setA - setB,再计算结果与setC的差集。

(2)SINTER命令用来对多个集合执行交集运算。集合A与集合B的交集表示为A ∩ B,代表所有属于A且属于B的元素构成的集合(如图3-14所示),即A ∩ B = {x | x ∈ A且x∈B}。例如:
在这里插入图片描述
在这里插入图片描述
SINTER命令的使用方法如下:

127.0.0.1:6379> sinter setA setB
1) "2"
2) "3"

SINTER命令同样支持同时传入多个键,如:

127.0.0.1:6379> sinter setA setB setC
1) "2"
2) "3"

(3)SUNION命令用来对多个集合执行并集运算。集合A与集合B的并集表示为A∪B,代表所有属于A或属于B的元素构成的集合(如图3-15所示),即A∪B = {x | x∈A或x ∈B}。例如:
在这里插入图片描述
在这里插入图片描述
SUNION命令的使用方法如下:

127.0.0.1:6379> sunion setA setB
1) "1"
2) "2"
3) "3"
4) "4"

SUNION命令同样支持同时传入多个键,例如:

127.0.0.1:6379> sunion setA setB setC
1) "1"
2) "2"
3) "3"
4) "4"

2.6 有序集合类

1.增加元素
在这里插入图片描述
ZADD命令用来向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。ZADD命令的返回值是新加入到集合中的元素个数(不包含之前已经存在的元素)。假设我们用有序集合模拟计分板,现在要记录Tom、Peter和David三名运动员的分数(分别是89分、67分和100分):

127.0.0.1:6379> zadd scoreboard 89 Peter 69 Piy 99 David
(integer) 3

这时我们发现Peter的分数录入有误,实际的分数应该是76分,可以用ZADD命令修改Peter的分数:

127.0.0.1:6379> zadd scoreboard 79 Peter
(integer) 0

分数不仅可以是整数,还支持双精度浮点数:

127.0.0.1:6379> zadd testboard 17e+307 a
(integer) 1
127.0.0.1:6379> zadd testboard 1.5 b
(integer) 1
127.0.0.1:6379> zadd testboard +inf c
(integer) 1
127.0.0.1:6379> zadd testboard -inf d
(integer) 1

其中+inf和-inf分别表示正无穷和负无穷。

2.获得元素的分数
在这里插入图片描述

127.0.0.1:6379> zscore scoreboard Tom
"89"

3.获得排名在某个范围的元素列表
在这里插入图片描述
ZRANGE命令会按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。ZRANGE命令与LRANGE命令十分相似,如索引都是从0开始,负数代表从后向前查找(-1表示最后一个元素)。就像这样:

127.0.0.1:6379> zrange scoreboard 0 2
1) "Tom"
2) "Peter"
3) "David"
127.0.0.1:6379> zrange scoreboard 1 -1
1) "Peter"
2) "David"

如果需要同时获得元素的分数的话可以在ZRANGE命令的尾部加上WITHSCORES参数,这时返回的数据格式就从“元素1,元素2,…,元素n”变为了“元素1,分数1,元素2,分数2,…,元素n, 分数n”,例如:

127.0.0.1:6379> zrange scoreboard 0 -1 withscores
1) "Tom"
2) "79"
3) "Peter"
4) "89"
5) "David"
6) "99"
7) "Did"

4.获得指定分数范围的元素
在这里插入图片描述
ZRANGEBYSCORE命令参数虽然多,但是都很好理解。该命令按照元素分数从小到大的顺序返回分数在min和max之间(包含min和max)的元素:

127.0.0.1:6379> zrangebyscore scoreboard 80 100
1) "Tom"
2) "David"

min和max还支持无穷大,同ZADD命令一样,-inf和+inf分别表示负无穷和正无穷。比如你希望得到所有分数高于80分(不包含80分)的人的名单,但你却不知道最高分是多少(虽然有些背离现实,但是为了叙述方便,这里假设可以获得的分数是无上限的),这时就可以用上+inf了:

127.0.0.1:6379> zrangebyscore scoreboard (80 +inf
1) "Tom"
2) "David"

5.增加某个元素的分数
在这里插入图片描述
ZINCRBY命令可以增加一个元素的分数,返回值是更改后的分数。例如,想给Jerry加4分:

127.0.0.1:6379> zincrby scoreboard 4 Jerry
"4"
127.0.0.1:6379> zincrby scoreboard 96 Jerry
"100"
127.0.0.1:6379> zincrby scoreboard -4 Jerry
"96"

如果指定的元素不存在,Redis在执行命令前会先建立它并将它的分数赋为0再执行操作。

发布了511 篇原创文章 · 获赞 822 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/YJG7D314/article/details/104625853
今日推荐