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 0 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