Redis基础知识(学习笔记9--Redis命令(2))

四. Hash型Value操作命令

Redis存储数据的Value可以是一个Hash类型。Hash类型也称为Hash表、字典等。

Hash表就是一个映射表Map,也是有键-值对构成,为了与整体的key进行区分,这里的键称为field,值称为value。

注意:Redis的Hash表中的field-value对均为String类型。

4.1 hset

>hset key field value

将哈希表key中的域field的值设为value。

说明:如果key不存在,一个新的哈希表被创建并进行hset 操作。如果域field已经存在于哈希表中,旧值将被覆盖。如果field是哈希表中的一个新建域,并且值设置成功,返回1。如果哈希表中域field已经存在且旧值已被新值覆盖,返回0。

4.2 hget

>hget key field

返回哈希表key中给定域field的值。

说明:当给定域不存在或是给定key不存在时,返回nil。

4.3 hmset

> hmset key field value [field value ...]

 同时将多个field-value(域-值)对设置到哈希表中。

说明:此命令会覆盖哈希表中已存在的域。如果key不存在,一个空哈希表被创建并执行hmset 操作。如果命令执行成功,返回OK。当key不是哈希表(hash)类型时,返回一个错误。

4.4 hmget

HMGET key field [field ...]

返回哈希表 key 中,一个或多个给定域的值。

说明:如果给定的域不存在于哈希表,那么返回一个 nil 值。因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。

一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。

4.5 hgetall

>HGETALL key

返回哈希表 key 中,所有的域和值。

说明:在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。

以列表形式返回哈希表的域和域的值。若 key 不存在,返回空列表。

4.6 hsetnx

>HSETNX key field value

将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。

说明:若域 field 已经存在,该操作无效。如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。

设置成功,返回 1 。如果给定域已经存在且没有操作被执行,返回 0 。

4.7 hdel

>HDEL key field [field ...]

删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。

说明:在Redis2.4以下的版本里, HDEL 每次只能删除单个域。返回值:被成功移除的域的数量,不包括被忽略的域。

4.8 hexists

>HEXISTS key field

查看哈希表 key 中,给定域 field 是否存在。

说明:如果哈希表含有给定域,返回 1 。如果哈希表不含有给定域,或 key 不存在,返回 0 。

4.9 hincrby 与 incrbyfloat

>hincrby key field increment

为哈希表key中的域field的值加上增量increment。hincrby命令只能增加整数值,而hincrbyfloat 可以增加小数值。

说明:增量也可以为负数,相当于对给定域进行减操作。如果key不存在,一个新的哈希表被创建并执行hincrby命令。如果域field不存在,那么在执行命令前,域的值被初始化为0。对一个储存字符串的域field执行hincrby命令会造成一个错误。

4.10 hkeys 与 hvals

>hkeys key 或者 hvals key

返回哈希表key中的所有域 或 所有值。

说明:当key不存在时,返回一个空表。

4.11 hlen

>HLEN key

返回哈希表 key 中域的数量。

说明:返回值为 哈希表中域的数量。当 key 不存在时,返回 0 。

4.12 hstrlen

>HSTRLEN key field

返回哈希表 key 中, 与给定域 field 相关联的值的字符串长度(string length)。

说明:返回值为一个整数。但是,如果给定的键或者域不存在, 那么命令返回 0 。

4.13 hscan

HSCAN key cursor [MATCH pattern] [COUNT count]

需要展开讲解。

4.14 应用场景

 hash型value 非常适合存储对象数据。key为对象名称,value为描述对象属性的Map,对对象属性的修改在Redis中就可以直接完成。其不像String型Value存储对象,那个对象是序列化过的,例如序列化为JSON串,对对象属性值的修改需要先反序列化为对象后再修改,修改后再序列化为JSON串后写入到Redis。

五. List 型Value操作命令

Redis存储数据的value 可以是一个String列表类型数据,即该列表中的每个元素均为string类型数据。列表中的数据会按照插入顺序进行排序。不过,该列表的底层实际是一个无头节点的双向列表,所以对列表表头与表尾的操作性能较高,但对中间元素的插入与删除的操作的性能相对较差。

5.1 lpush / rpush

>lpush key value [value ...]  或 rpush key value [value ...]

将一个或多个值value 插入到列表key的表头 / 表尾 (表头在左表尾在右)。

说明:如果有多个value,对于lpush来说,各个value会按从左到右的顺序依次插入到表头;对于rpush来说,各个value会按从左到右的顺序依次插入到表尾。如果key不存在,一个空列表会被创建并执行。当key存在但不是列表类型时,返回一个错误。执行成功时,返回列表的长度。

 顺序描述的可能有点乱,举例说明下:

LPUSH

redis> LPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"

RPUSH

redis> RPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"

 5.2 llen

>llen key

返回列表key的长度。

说明:如果key不存在,则key被解释为一个空列表,返回0,如果key不是列表类型,返回一个错误。

5.3 lindex

>lindex key index

返回列表key中,下标为index的元素,列表从0开始计数。

说明:如果inde参数的值不住列表的区间范围内(out of range),返回nil。

5.4 lset

>LSET key index value

将列表 key 下标为 index 的元素的值设置为 value 。

说明:当 index 参数超出范围,或对一个空列表( key 不存在)进行 LSET 时,返回一个错误。操作成功返回 ok ,否则返回错误信息。

需要注意的是:对头元素或尾元素进行 LSET 操作,复杂度为 O(1)。其他情况下,为 O(N), N 为列表的长度。

5.5 lrange

>LRANGE key start stop

返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。

说明:下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。超出范围的下标值不会引起错误。如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,那么 LRANGE 返回一个空列表。如果 stop 下标比 end 下标还要大,Redis将 stop 的值设置为 end 。返回值:一个列表,包含指定区间内的元素。

注意LRANGE命令和编程语言区间函数的区别:假如你有一个包含一百个元素的列表,对该列表执行 LRANGE list 10 ,结果是一个包含11个元素的列表,这表明 stop 下标也在 LRANGE 命令的取值范围之内(闭区间),这和某些语言的区间函数可能不一致,比如Ruby的 Range.new 、 Array#slice 和Python的 range() 函数。

5.6  lpushx / rpushx

>LPUSHX key value

将值 value 插入到列表 key 的表头,当且仅当 key 存在并且是一个列表。

说明:和 LPUSH 命令相反,当 key 不存在时, LPUSHX 命令什么也不做。返回值:LPUSHX 命令执行之后,表的长度。

>RPUSHX key value

将值 value 插入到列表 key 的表尾,当且仅当 key 存在并且是一个列表。

说明:和 RPUSH 命令相反,当 key 不存在时, RPUSHX 命令什么也不做。返回值:RPUSHX 命令执行之后,表的长度。

5.7 linsert 

>linsert key before | after pivot value

将值value插入到列表key当中,位于元素pivot之前或之后。

说明:当pivot元素不存在于列表当中时,不执行任何操作,返回-1;当key不存在时,key被视为空列表,不执行任何操作,返回0;如果key不是类别类型,返回一个错误;如果命令执行成功,返回插入操作完成之后,列表的长度。

5.8 lpop / rpop

>lpop key [count] / rpop key [count]

从列表key的表头 / 表尾 移除 count个元素,并返回移除的元素。count 默认值为1。

说明:当key不存在时,返回nil。

5.9 blpop / brpop

>blpop key [key ... ] timeout / brpop key [key ...] timeout

blpop / brpop 时列表的阻塞式(blocking)弹出命令。它们是blpop / brpop命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 blpop / brpop 命令阻塞,直到timeout超时或者发现可弹出元素为止。当给定多个key参数时,按参数key的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。timeout为阻塞时长,单位为秒,其值若为0,则表示只要没有可弹出元素,则一直阻塞。

说明:假如在指定时间内没有任何元素被弹出,则返回一个nil 和等待时长。反之,返回一个含有两个元素的列表,第一个元素时被弹出元素所属的key,第二个元素时被弹出的元素的值。

5.10 rpoplpush

>rpoplpush source destination

在一个原子时间内,执行以下两个动作:

* 将列表source中的最后一个元素(尾元素)弹出,并返回给客户端;

*将source弹出的元素插入到列表destination,作为destination列表的头元素。

说明:如果source不存在,值nil被返回,并且不执行其他动作。如果source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。

 5.11 brpoplpush

>brpoplpush source destimation timeout

brpoplpush 是 rpoplpush的阻塞版本,当给定列表source不为空时,brpoplpush的表现和rpoplpush一样。当列表source为空时,brpoplpush的命令为阻塞连接,直到等待超时,或有另一个客户端对source执行lpush或者rpush命令为止。timeout为阻塞时长,单位为秒,其值若为0,则表示只要没有可弹出元素,则一直阻塞。

说明:假如在指定时间内没有任何元素被弹出,则返回一个nil和等待时长。反之,返回一个含有两个元素的列表,第一个元素是被弹出的值,第二个是等待时长。

5.12 lrem

>lrem key count value

根据参数count的值,移除类别中与参数value相同的元素。count的值可以有以下一种:

*** count>0:从表头开始向表尾搜索,移除与value 相等的元素,数量为count。

*** count<0:从表尾开始向表头搜索,移除与value 相等的元素,数量为count的绝对值。

*** count=0:移除表中所有与value 相等的元素。

说明:返回被移除元素的数量。当key不存在时,lrem命令返回0,因为不存在的key被视为空表(empty list)。

5.13 ltrim

>ltrim key start stop

对一个列表进行修剪(trim),即让列表只保留指定区间内的元素,不在指定区间之内的元素都将被移除。

说明:下标(index)参数start 和 stop 都是以0为底,即以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。当key不是列表类型时,返回一个错误。如果start下标比列表的最大下标end(llen list 减去1)还要大,或者start>end,ltrim返回一个空列表,因为ltrim已将整个列表清空。

5.14 主要应用场景

通过构建不通的数据结构来实现相应的业务功能。

(1)栈

通过lpush + lpop 可以实现栈数据结构:先进后出。通过lpush从列表左侧插入数据,通过lpop从列表左侧取出数据。当然rpush+rpop也可以实现相同效果,只不过操作的时列表右侧。

(2)队列

通过lpush +rpop 可以实现队列数据结构效果:先进先出。通过lpush从列表左侧插入数据,通过rpop从列表右侧取出数据。当然,通过rpush + lpop也可以实现相同的效果,只不过操作的方向与前者组合相反。

(3)阻塞式消息队列

通过lpush+brpop 可以实现阻塞式消息队列效果。作为消息生产者的客户端使用lpush从列表左侧插入数据,作为消息消费者的多个客户端使用brpop阻塞是”抢占“列表尾部数据进行消费,保证了消费的负载均衡与高可用性。

(4)动态有限集合

通过lpush+ltrim可以实现有限集合。通过lpush从列表左侧向列表中添加数据,通过ltrim保持集合的动态有限性。当然,通过rpush+ltrim也可以实现相同效果,只不过操作的方向正好相反。

 

 

学习参阅声明

1.【Redis视频从入门到高级】

https://www.bilibili.com/video/BV1U24y1y7jF?p=11&vd_source=0e347fbc6c2b049143afaa5a15abfc1c】

2. 【Redis 命令参考】

https://haiyong.site/doc/redis/redis-gh-pages/hash/hscan.html

热门相关:婚婚欲睡:腹黑老公请节制   一世倾心:误惹腹黑师弟   妖魔哪里走   呆萌小萝莉:高冷男神太腹黑   以权谋妻