3.4 Hash型Value命令
Hash 表就是一个映射表 Map,也是由键-值对构成,为了与整体的 key 进行区分,这里的键称为 field,值称为 value。注意,Redis 的 Hash 表中的 field-value 对均为 String 类型。
3.4.1 hset
格式: HSET key field1 value1 [field2 value2 …]
功能:将哈希表 key 中的字段 field 的值设为 value 。
返回值:
a. 若仅修改返回0 ;
b. 仅新增 , 同时新增和修改时, 返回新增的个数
c. 若key已存在, 且并不是哈希表, 返回错误
说明:如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。如果字段 field 已经存在于哈希表中,旧值将被覆盖。
3.4.2 HGET
格式:HGET key field
功能:返回哈希表 key 中给定字段 field 的值。
返回值:当给定字段不存在或是给定 key 不存在时,返回 nil 。
3.4.3 HMSET
就是HSET的多键值对版本, 可以一次向哈希表key中插入多个键值对, 但从4.0版本之后 , HSET可以也可以实现插入多个键值对, HMSET不再推荐使用.
3.4.4 HMGET
格式:HMGET key field [field …]
功能:按照给出顺序返回哈希表 key 中一个或多个字段的值。
返回值:当给定字段不存在或是给定 key 不存在时,返回 nil 。
3.4.5 HGETALL
返回值:
a. 返回哈希表key中的所有键值对, 每个字段(field name)之后是字段的值(value),所以返回值的长度是哈希表大小的两倍。
b .当给定字段不存在或是给定 key 不存在时,返回 nil 。
阻塞系统 . 生产环境中一般不使用该命令,而使用 hscan 命令代替。
3.4.6 HSETNX
格式:HSETNX key field value
功能:仅为哈希表key中不存在的字段field赋值
返回值:
a, 若字段 field 已经存在,该操作无效。返回0
b. 若哈希表key 不存在,一个新哈希表被创建并执行 HSETNX 命令。返回1
3.4.7 HDEL
格式:HDEL key field1 [field2 …]
功能:删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。
返回值:被成功移除的字段的数量,不包括被忽略的字段。
3.4.8 HEXISTS
格式:HEXISTS key field
功能:查看哈希表 key 中给定字段 field 是否存在。
返回值:如果哈希表含有给定字段,返回 1 。如果不含有给定字段,或 key 不存在,返回 0 。
3.4.9 HINCRBY 与 HINCRBYFLOAT
格式:HINCRBY key field increment
功能:为哈希表 key 中的字段 field 的值加上增量 increment 。hincrby 命令只能增加整数值,而 hincrbyfloat 可以增加小数值。增量也可以为负数,相当于对给定字段进行减法操作。
返回值:
a. 如果 哈希表key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。并返回执行后字段字段field的value
b. 如果字段 field 不存在,那么在执行命令前,字段的值被初始化为 0。并返回执行后字段field的value
c. 对储存字符串值的字段 field 执行 HINCRBY 命令 , 将返回一个错误。
3.4.10 HKEYS 与 HVALS
格式:HKEYS key 或 HVALS key
功能:返回哈希表 key 中的所有字段/值。
返回值:当 key 不存在时,返回空表提示HKEYS fake_key (empty list or set)。
3.4.11 HLEN
格式:HLEN key
功能:返回哈希表 key 中字段的数量。
返回值:当 哈希表key 不存在时,返回 0 。
3.4.12 HSTRLEN
格式:HSTRLEN key field
功能:返回哈希表 key 中, 与给定字段 field 相关联的值的字符串长度(string length)。
返回值:如果给定的键key或者字段field不存在, 那么命令返回 0 。
3.4.13 应用场景
Hash 型 Value 非常适合存储对象数据。key 为对象名称,value 为描述对象属性的 Map,对对象属性的修改在 Redis 中就可直接完成。
作为对比 :
一个普通的对象, 必须将其序列化为JSON后才能存储进String 型 Value 中. 因此, 若要修改对象属性, 先要读出String型Value值, 然后将其反序列化回对象后再修改,修改后再序列化为 JSON 串后写入到 Redis, 可以看出非常复杂。
然而, 在实际应用中, 为了操作命令的统一, 包括hash / list / set /zset 所有都用String类型解决.
3.5 List型Value命令
List型Value, 即value属性中存储的是一个String型的列表, 列表中的数据会按照插入顺序进行排序。不过,该列表的底层实际是一个无头节点的双向链表,所以对列表表头与表尾的操作性能较高,但对中间元素的插入与删除的操作的性能相对较差。
3.5.1 LPUSH/RPUSH
格式: LPUSH key value1 [value2 …] 或 RPUSH key value1 [value1 …]
功能:将一个或多个值 value 插入到列表 key 的表头/表尾(表头在左表尾在右)
说明:
如果有多个 value 值,对于 LPUSH 来说,各个 value 会按从左到右的顺序依次插入到表头;对于 RPUSH 来说,各个 value 会按从左到右的顺序依次插入到表尾。执行成功时返回列表的长度。
如果 key不存在,一个空列表会被创建并执行操作。
当 key 存在但不是列表类型时,返回一个错误。
3.5.2 LSET
格式:LSET key index value
功能:将列表 key 下标为 index 的元素的值设为 value 。
说明:当 index 参数超出范围,或对一个空列表(key 不存在)进行 LSET 时,返回一个错误。
3.5.3 LLEN
格式:LLEN key
功能:返回存储在 key 中的列表长度。 。
说明:
a. 如果 key 不存在,则 key 被解释为一个空列表,返回 0 。
b. 如果 key 不是列表类型,返回一个错误。
3.5.4 LINDEX
格式:LINDEX key index
功能:返回列表 key 中,下标为 index 的元素。列表从 0 开始计数。
说明:如果 index 参数的值不在列表的区间范围内(out of range),返回 nil 。
3.5.5 LRANGE
格式:LRANGE key start stop
功能:返回列表 key 中指定区间[start, stop]内的元素,即包含两个端点。
返回值:
可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素。
超出范围的下标值不会引起错误。
如果 start 下标比列表的最大下标还要大,那么 返回一个空列表。
如果 stop 下标比最大下标还要大,Redis将数组stop改为数组最后一个元素下标后执行。
3.5.6 LPUSHX 与 RPUSHX
格式:LPUSHX key value 或 RPUSHX key value
功能:仅当 key 存在并且是一个列表时, 将值 value 插入到列表 key 的表头/表尾
说明:
a. 当 key 不存在时,命令什么也不做。
b. 若执行成功,则输出表的长度。
3.5.7 LINSERT
格式:LINSERT key BEFORE|AFTER pivot value
功能:将值 value 插入到列表 key 当中,位于元素 pivot 之前或之后。
返回值:
a. 当 key 不存在时, key 被视为空列表,不执行任何操作,返回 0;
b. 当 pivot 元素不存在于列表中时,不执行任何操作,返回-1;
c. 如果 key 不是列表类型,返回一个错误;
d. 如果命令执行成功,返回插入操作完成之后,列表的长度。
3.5.8 LPOP / RPOP
格式:LPOP key [count] 或 RPOP key [count]
功能:从列表 key 的表头/表尾移除 count 个元素,并返回移除的元素。count 默认值 1
返回值:当 key 不存在时,返回 nil
3.5.9 BLPOP / BRPOP
格式:BLPOP key1 [key2 …] timeout 或 BRPOP key1 [key2 …] timeout
功能:BLPOP/BRPOP 是列表的阻塞式(blocking)弹出命令。它们是 LPOP/RPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP/BRPOP 命令阻塞,直到等待 timeout 超时或发现可弹出元素为止。当给定多个 key 参数时,按参数 key的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。timeout 为阻塞时长,单位为秒,其值若为 0,则表示只要没有可弹出元素,则一直阻塞。
说明:假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值。
3.5.10 LTRIM
格式:LTRIM key start stop
功能:对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
说明:
可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
当 key 不是列表类型时,返回一个错误。
如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,或者 start > stop , LTRIM 返回一个空列表,因为 LTRIM 已经将整个列表清空。
如果 stop 下标比 end 下标还要大,Redis 将 stop 的值设置为 end 。
3.5.X 应用场景
Value 为 List 类型的应用场景很多,主要是通过构建不同的数据结构来实现相应的业务功能。这里仅对这些数据结构的实现方式进行总结,不举具体的例子。
(1) 栈
通过 LPUSH + LPOP 可以实现栈数据结构效果:先进后出。通过 LPUSH 从列表左侧插入数据,通过 LPOP 从列表左侧取出数据。当然,通过 RPUSH + RPOP 也可以实现相同效果,只不过操作的是列表右侧。
(2) 队列
通过 LPUSH + RPOP 可以实现队列数据结构效果:先进先出。通过 LPUSH 从列表左侧插入数据,通过 RPOP 从列表右侧取出数据。当然,通过 RPUSH + LPOP 也可以实现相同效果,只不过操作的方向正好相反。
(3) 阻塞式消息队列
通过 lpush + brpop 可以实现阻塞式消息队列效果。作为消息生产者的客户端使用 lpush从列表左侧插入数据,作为消息消费者的多个客户端使用 brpop 阻塞式“抢占”列表尾部数据进行消费,保证了消费的负载均衡与高可用性。brpop 的 timeout 设置为 0,表示只要没有数据可弹出,就永久阻塞。
(4) 动态有限集合
通过 lpush + ltrim 可以实现有限集合。通过 lpush 从列表左侧向列表中添加数据,通过ltrim 保持集合的动态有限性。像企业的末位淘汰、学校的重点班等动态管理,都可通过这种动态有限集合来实现。当然,通过 rpush + ltrim 也可以实现相同效果,只不过操作的方向正好相反。
3.6 Set 型 Value 操作命令
Redis 存储数据的 Value 可以是一个 Set 集合,且集合中的每一个元素均 String 类型。
Set与 List 在表现上非常相似,但实质却非常不同:
a. Set底层是一个Hash表, List底层是一个无头结点的双向链表
b. 因此, Set 中的元素具有无序性与不可重复性,而 List 则具有有序性与可重复性。
3.6.1 sadd
格式:SADD key member1 [member2 …]
功能:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member元素将被忽略。
返回值:
a. 若 key 不存在,则创建一个只包含 member 元素作成员的集合, 并返回添加到集合里元素的数量。
b. 若 key 不是集合类型,返回一个错误。
3.6.2 SMEMBERS
格式:SMEMBERS key
功能:返回集合 key 中的所有成员。
说明:
a. 不存在的 key 被视为空集合。
b. 若 key 中包含大量元素,则该命令可能会阻塞 Redis服务。所以生产环境中一般不使用该命令,而使用 sscan 命令代替。
3.6.3 SCARD
格式:SCARD key
功能:返回 Set 集合的长度
说明:当 key 不存在时,返回 0 。
3.6.4 SISMEMBER
格式:SISMEMBER key member
功能:判断 member 元素是否集合 key 的成员。
说明:
a. 如果 member 元素是集合的成员,返回 1 。
b. 如果 member 元素不是集合的成员,或 key 不存在,返回 0 。
3.6.5 SMOVE
格式:SMOVE source destination member
功能:将 member 元素从 source 集合移动到 destination 集合。
说明:
a. 如果 source 集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回 0 。
b. 当 destination 集合已经包含 member 元素时, SMOVE命令只是简单地将 source 集合中的 member 元素删除。
c. 当 source 或 destination 不是集合类型时,返回一个错误。
d. 一切正常, 则 member 元素从 source 集合中被移除,并添加到destination 集合中去,返回 1。
3.6.6 SREM
格式:SREM key member1 [member2 …]
功能:移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略,且返回成功移除的元素个数。
说明:当 key 不是集合类型,返回一个错误。
3.6.7 SRANDMEMBER
格式:SRANDMEMBER key [count]
功能:返回集合中的 count 个随机元素。count 默认值为 1。
说明:
a. 若 count 为正数,且小于集合长度,那么返回一个包含 count 个元素的数组,数组中的元素各不相同。
b. 如果 count 大于等于集合长度,那么返回整个集合。
c. 如果count 为负数,那么返回一个包含 count 绝对值个元素的数组,但数组中的元素可能会出现重复。
3.6.8 SPOP
格式:SPOP key [count]
功能:移除并返回集合中的 count 个随机元素。count 必须为正数,且默认值为 1。
说明:
a. count为0或负数时返回空
b. count合适时, 返回所有被随机删除的元素
c. 如果 count 大于等于集合长度,那么移除并返回整个集合。
3.6.9
3.7 有序集合ZSET
Redis 存储数据的 Value 可以是一个有序 Set,这个有序 Set 中的每个元素均 String 类型。有序 Set 与 Set 的不同之处是,有序 Set 中的每一个元素都有一个分值 score,Redis 会根据score 的值对集合进行由小到大的排序。其与 Set 集合要求相同,元素不能重复,但元素的score 可以重复。由于该类型的所有命令均是字母 z 开头,所以该 Set 也称为 ZSet。
3.7.1 ZADD
格式:ZADD key score1 member1 [[score2 member2]
功能:将一个或多个 member 元素及其 score 值加入到有序集 key 中的适当位置。
说明:score 值可以是整数值或双精度浮点数。
a. 如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
b. 当 key 存在但不是有序集类型时,返回一个错误。
c. 若写入的 member 值已经存在,但 score 值不同,则新的 score 值将覆盖老 score。
c. 如果命令执行成功,则返回被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
3.7.2 ZRANGE 与 ZREVRANGE
格式:ZRANGE key start stop [WITHSCORES] 或 ZREVRANGE key start stop [WITHSCORES]
功能:返回有序集 key 中,指定区间内的成员。zrange 命令会按 score 值递增排序, zrevrange命令会按score递减排序。具有相同 score 值的成员按字典序/逆字典序排列。可以通过使用 WITHSCORES 选项,来让成员和它的 score 值一并返回。
说明:
a. 可以使用负数下标,-1 表示最后一个成员,-2 表示倒数第二个成员,以此类推。超出范围的下标并不会引起错误, 处理逻辑与之前LRANGE命令一致.
b.可能会阻塞 Redis 服务。所以生产环境中如果要查询有序集合中的所有元素使用 zscan 命令代替。
3.7.3 ZRANGEBYSCORE 与 ZREVRANGEBYSCORE
格式:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
功能:返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或max )的成员。有序集成员按 score 值递增/递减次序排列。具有相同 score 值的成员按字典序/逆字典序排列。可选的 LIMIT 参数指定返回结果的数量及区间(就像 SQL 中的SELECT LIMIT offset, count ),注意当 offset 很大时,定位 offset 的操作可能需要遍历整个有序集,此过程效率可能会较低。可选的 WITHSCORES 参数决定结果集是单单返回有序集的成员,还是将有序集成员及其 score 值一起返回。
说明:min 和 max 的取值是正负无穷大的。默认情况下,区间的取值使用闭区间 (小于等于或大于等于),也可以通过给参数前增加左括号“(”来使用可选的开区间 (小于或大于)。
3.7.15 应用场景
有序 Set 最为典型的应用场景就是排行榜,例如音乐、视频平台中根据播放量进行排序的排行榜;电商平台根据用户评价或销售量进行排序的排行榜等。将播放量作为 score,将作品 id 作为 member,将用户评价积分或销售量作为 score,将商家 id 作为 member。使用zincrby 增加排序 score,使用 zrevrange 获取 Top 前几名,使用 zrevrank 查询当前排名,使用zscore 查询当前排序 score 等。