4

Redis指令2:五种常用数据类型操作命令

 3 years ago
source link: https://maxqiu.com/article/detail/96
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文档整理自教程:
Redis官方文档:commands
尚硅谷视频:尚硅谷_Redis6


本文仅介绍常用命令,所有命令请参考官方文档

String 字符串

  • StringRedis最基本的类型,可以理解成与Memcached一模一样的类型,一个key对应一个value
  • String类型是二进制安全的。意味着RedisString可以包含任何数据。比如jpg或者序列化的对象。
  • 一个Redis中字符串value最多可以是512M

String的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内部结构实现上类似于JavaArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。

如图中所示:内部为当前字符串实际分配的空间capacity,一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间。需要注意的是字符串最大长度为512M

GET key 获取值

自1.0.0起可用。

获取key的值。如果键不存在,则返回特殊值nil。如果存储在key的值不是字符串,则返回错误,因为GET仅处理字符串值。

  1. 127.0.0.1:6379> GET nonexisting
  2. (nil)
  3. 127.0.0.1:6379> SET key hello
  4. OK
  5. 127.0.0.1:6379> GET key
  6. "hello"

GETEX key 获取值并设置有效时间

自6.2.0起可用。

获取key的值,并可以选择设置其过期时间。GETEXGET相似,但是是带有附加选项的写命令。

选项:该GETEX命令支持一组修改其行为的选项,具体如下:

  • EX seconds:设置指定的到期时间(以秒为单位)
  • PX milliseconds:设置指定的过期时间(以毫秒为单位)
  • EXAT timestamp-seconds:设置密钥过期的指定Unix时间,以秒为单位
  • PXAT timestamp-milliseconds:设置密钥过期的指定Unix时间(以毫秒为单位)
  • PERSIST:保留与键关联的生存时间
  1. 127.0.0.1:6379> SET key hello
  2. OK
  3. 127.0.0.1:6379> GETEX key
  4. "hello"
  5. 127.0.0.1:6379> TTL key
  6. (integer) -1
  7. 127.0.0.1:6379> GETEX key EX 60
  8. "hello"
  9. 127.0.0.1:6379> TTL key
  10. (integer) 60

GETDEL key 获取键的值同时删除键

自6.2.0起可用。

获取key的值并删除当前key。此命令与GET相似,不同之处在于它也会在成功时删除键(当且仅当键的值类型为字符串时)。

  1. 127.0.0.1:6379> SET key hello
  2. OK
  3. 127.0.0.1:6379> GETDEL key
  4. "hello"
  5. 127.0.0.1:6379> GET key
  6. (nil)

SET key value 设置键与值

SET key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL] [NX|XX] [GET]

自1.0.0起可用。

设置key保存一个值。如果key已经保存了一个值,则无论其类型如何,都会覆盖该值。成功进行SET操作后,将丢弃与键关联的任何以前的时间。与键关联的任何有效时间都将被丢弃。

选项:SET命令支持一组修改其行为的选项,具体如下:

  • EX seconds:设置指定的到期时间(以秒为单位)
  • PX milliseconds:设置指定的过期时间(以毫秒为单位)
  • EXAT timestamp-seconds:设置密钥过期的指定Unix时间,以秒为单位
  • PXAT timestamp-milliseconds:设置密钥过期的指定Unix时间(以毫秒为单位)
  • KEEPTTL:保留与键关联的生存时间
  • NX:仅设置不存在的密钥
  • XX:仅设置密钥(如果已存在)
  • GET:返回存储在key处的旧值;如果key不存在,则返回nil
  • OK:如果SET执行正确
  • 字符串:设置GET选项时,旧值存储在key处;如果key不存在,则为nil
  • nil:如果由于用户指定了NXXX选项但不满足条件而未执行SET操作,或者如果用户指定了GET选项并且该键没有先前的值,则返回nil
  1. 127.0.0.1:6379> SET key hello
  2. OK
  3. 127.0.0.1:6379> GET key
  4. "hello"
  5. 127.0.0.1:6379> SET key2 hello EX 60
  6. OK
  7. 127.0.0.1:6379> GET key2
  8. "hello"
  9. 127.0.0.1:6379> TTL key2
  10. (integer) 60
  11. 127.0.0.1:6379> SET key word NX
  12. (nil)
  13. 127.0.0.1:6379> SET key word XX
  14. OK
  15. 127.0.0.1:6379> GET key
  16. "word"
  17. 127.0.0.1:6379> SET key tom GET
  18. "word"
  19. 127.0.0.1:6379> GET key
  20. "tom"

SETEX key seconds value 设置键与值并设置超时时间(秒)

自2.0.0起可用。

设置key的值设置超时时间(秒)。此命令等效于执行以下命令:

  1. SET mykey value
  2. EXPIRE mykey seconds

SETEX是原子性的,可以通过在MULTI / EXEC块中使用前面两个命令来实现。它提供了一个更快的替代给定的操作序列,当Redis被用作缓存时,这个操作是非常常见的。

  1. 127.0.0.1:6379> SETEX key 10 hello
  2. OK
  3. 127.0.0.1:6379> TTL key
  4. (integer) 10

PSETEX key milliseconds value 设置键与值并设置超时时间(毫秒)

自2.6.0起可用。

PSETEX的工作方式与SETEX完全相同,唯一的区别是到期时间以毫秒而不是指定秒为单位。

  1. 127.0.0.1:6379> PSETEX key 10000 hello
  2. OK
  3. 127.0.0.1:6379> PTTL key
  4. (integer) 4397

SETNX key value 键不存在则设置键与值

自1.0.0起可用。

设置key的值,如果key不存在,则等于SET。如果key已经拥有一个值,则不执行任何操作。

  1. 127.0.0.1:6379> SETNX key hello
  2. (integer) 1
  3. 127.0.0.1:6379> SETNX key hello
  4. (integer) 0
  5. 127.0.0.1:6379> GET key
  6. "hello"

GETSET key value 获取值并设置一个新值

注:自Redis 6.2起,已弃用!请使用带有GET参数的SET命令

自1.0.0起可用。

以原子方式设置keyvalue并返回存储在key中的旧值。如果key存在但不包含字符串值,则返回错误。

  1. 127.0.0.1:6379> SET key hello
  2. OK
  3. 127.0.0.1:6379> GETSET key world
  4. "hello"
  5. 127.0.0.1:6379> GET key
  6. "world"

APPEND key value 拼接字符串

自2.0.0起可用。

如果key已经存在并且是字符串,则此命令将value附加在字符串的末尾。如果key不存在,则会创建它并将其设置为空字符串,因此APPEND在这种特殊情况下将类似于SET。该命令返回值为整数:即追加操作后字符串的长度。

  1. 127.0.0.1:6379> EXISTS key
  2. (integer) 0
  3. 127.0.0.1:6379> APPEND key hello
  4. (integer) 5
  5. 127.0.0.1:6379> APPEND key " world"
  6. (integer) 11
  7. 127.0.0.1:6379> GET key
  8. "hello world"

STRLEN key

自2.2.0起可用。

返回存储在key中的字符串值的长度。key的值为非字符串时,将返回错误。

  1. 127.0.0.1:6379> SET key hello
  2. OK
  3. 127.0.0.1:6379> STRLEN key
  4. (integer) 5
  5. 127.0.0.1:6379> STRLEN nonexisting
  6. (integer) 0

GETRANGE key start end 截取字符串

自2.4.0起可用。

返回key的字符串值的子字符串,由偏移量的startend决定(都包括在内)。可以使用负偏移量来提供从字符串末尾开始的偏移量。所以-1是最后一个字符,-2是倒数第二个字符,以此类推。该函数通过将结果范围限制为字符串的实际长度来处理超出范围的请求。

  1. 127.0.0.1:6379> SET key "This is a string"
  2. OK
  3. 127.0.0.1:6379> GETRANGE key 0 3
  4. "This"
  5. 127.0.0.1:6379> GETRANGE key -3 -1
  6. "ing"
  7. 127.0.0.1:6379> GETRANGE key 0 -1
  8. "This is a string"
  9. 127.0.0.1:6379> GETRANGE key 10 100
  10. "string"

SETRANGE key offset value 修改字符串

自2.2.0起可用。

从指定的偏移量开始,覆盖key存储的字符串的一部分,覆盖value的整个长度。如果偏移量大于键处字符串的当前长度,则用零字节填充字符串以使偏移量适合。不存在的键被认为是空字符串,所以这个命令将确保它保存的字符串足够大,能够在offset处设置value。该命令返回被修改后的字符串长度

  1. 127.0.0.1:6379> SET key "Hello World"
  2. OK
  3. 127.0.0.1:6379> SETRANGE key 6 redis
  4. (integer) 11
  5. 127.0.0.1:6379> GET key
  6. "Hello redis"

INCR key 加一 | DECR key 减一

自1.0.0起可用。

key的值的数字加1或减1。如果key不存在,则将其设置为0,然后再执行操作。如果key包含错误类型的值或包含不能表示为整数的字符串,则返回错误。该操作仅限于64位有符号整数。注意:这是一个字符串操作,因为Redis没有一个专用的整数类型。该操作返回递增或递减后的key的值

  1. 127.0.0.1:6379> SET key 0
  2. OK
  3. 127.0.0.1:6379> INCR key
  4. (integer) 1
  5. 127.0.0.1:6379> INCR key
  6. (integer) 2
  7. 127.0.0.1:6379> DECR key
  8. (integer) 1
  9. 127.0.0.1:6379> DECR key
  10. (integer) 0
  11. 127.0.0.1:6379> DECR key
  12. (integer) -1

INCRBY key increment 加指定值 | DECRBY key decrement | 减指定值

自1.0.0起可用。

  • INCRBY key increment:按增量increment增加存储在键上的数字
  • DECRBY key decrement:以递减decrement的方式递减存储在键中的数字。

如果密钥不存在,则将其设置为0,然后再执行操作。如果键包含错误类型的值或包含不能表示为整数的字符串,则返回错误。该操作仅限于64位有符号整数。

  1. 127.0.0.1:6379> SET key 5
  2. OK
  3. 127.0.0.1:6379> INCRBY key 3
  4. (integer) 8
  5. 127.0.0.1:6379> DECRBY key 10
  6. (integer) -2

MGET key [key …] 批量获取值

自1.0.0起可用。

返回所有指定键的值。对于每个不包含字符串值或不存在的键,将返回特殊值nil。因此,操作永远不会失败。

  1. 127.0.0.1:6379> SET key1 hello
  2. OK
  3. 127.0.0.1:6379> SET key2 world
  4. OK
  5. 127.0.0.1:6379> MGET key1 key2 key3
  6. 1) "hello"
  7. 2) "world"
  8. 3) (nil)

MSET key value [key value …] 批量设置值

自1.0.1起可用。

将给定的键设置为其各自的值。像常规的SET一样,MSET用新值替换现有值。如果不想覆盖现有值,请参阅MSETNXMSET是原子性的,所以所有给定的键都是一次性设置的。客户端不可能看到一些键被更新而另一些键没有改变。

  1. 127.0.0.1:6379> MSET key1 hello key2 world
  2. OK
  3. 127.0.0.1:6379> MGET key1 key2
  4. 1) "hello"
  5. 2) "world"

MSETNX key value [key value …] 批量设置值(仅当键不存在)

自1.0.1起可用。

将给定的键设置为其各自的值。即使只有一个键已经存在,MSETNX也不会执行任何操作。因为这个语义MSETNX可以用来设置表示一个唯一逻辑对象的不同字段的不同键,以确保要么设置所有字段,要么根本不设置。MSETNX是原子性的,所以所有给定的键都是一次性设置的。客户端不可能看到一些键被更新而另一些键没有改变。

  1. 127.0.0.1:6379> MSETNX key1 hello key2 world
  2. (integer) 1
  3. 127.0.0.1:6379> MSETNX key3 redis key2 world
  4. (integer) 0
  5. 127.0.0.1:6379> MGET key1 key2 key3
  6. 1) "hello"
  7. 2) "world"
  8. 3) (nil)

List 列表

Redis列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。

List的数据结构为快速链表quickList。首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也即是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成quicklist。因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是int类型的数据,结构上还需要两个额外的指针prevnext

Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。

LRANGE key start stop 按指定范围查看列表的值

自1.0.0起可用。

返回存储在键的列表的指定元素。偏移量startstop是从0开始的。0是列表的第一个元素(列表的头),1是下一个元素,以此类推。这些偏移量也可以是负数,表示从列表末尾开始的。例如,-1是列表的最后一个元素,-2倒数第二个,依此类推。超出范围的索引不会产生错误。如果start大于列表的末尾,则返回一个空列表。如果stop大于列表的实际末尾,则Redis会将其视为列表的最后一个元素。

  1. 127.0.0.1:6379> RPUSH list 1
  2. (integer) 1
  3. 127.0.0.1:6379> RPUSH list 2
  4. (integer) 2
  5. 127.0.0.1:6379> RPUSH list 3
  6. (integer) 3
  7. 127.0.0.1:6379> LRANGE list 0 0
  8. 1) "1"
  9. 127.0.0.1:6379> LRANGE list -3 -2
  10. 1) "1"
  11. 2) "2"
  12. 127.0.0.1:6379> LRANGE list -100 100
  13. 1) "1"
  14. 2) "2"
  15. 3) "3"
  16. 127.0.0.1:6379> LRANGE list 100 200
  17. (empty array)

RPUSH key element [element …] 在列表右侧插值 | LPUSH key element [element …] 在列表左侧插值

自1.0.0起可用。

key存储的列表头部或尾部插入所有指定的值。如果key不存在,则在执行推操作之前将其创建为空列表。如果key保存的值不是列表,则返回错误。只要在命令末尾指定多个参数,就可以使用一个命令调用推入多个元素。该命令返回推送操作后列表的长度。

例:RPUSH

  1. 127.0.0.1:6379> RPUSH list1 a
  2. (integer) 1
  3. 127.0.0.1:6379> RPUSH list1 b
  4. (integer) 2
  5. 127.0.0.1:6379> RPUSH list1 c
  6. (integer) 3
  7. 127.0.0.1:6379> LRANGE list1 0 -1
  8. 1) "a"
  9. 2) "b"
  10. 3) "c"
  11. 127.0.0.1:6379> RPUSH list1 d e f
  12. (integer) 6
  13. 127.0.0.1:6379> LRANGE list1 0 -1
  14. 1) "a"
  15. 2) "b"
  16. 3) "c"
  17. 4) "d"
  18. 5) "e"
  19. 6) "f"

例:LPUSH

  1. 127.0.0.1:6379> LPUSH list2 a
  2. (integer) 1
  3. 127.0.0.1:6379> LPUSH list2 b
  4. (integer) 2
  5. 127.0.0.1:6379> LPUSH list2 c
  6. (integer) 3
  7. 127.0.0.1:6379> LRANGE list2 0 -1
  8. 1) "c"
  9. 2) "b"
  10. 3) "a"
  11. 127.0.0.1:6379> LPUSH list2 d e f
  12. (integer) 6
  13. 127.0.0.1:6379> LRANGE list2 0 -1
  14. 1) "f"
  15. 2) "e"
  16. 3) "d"
  17. 4) "c"
  18. 5) "b"
  19. 6) "a"

RPUSHX key element [element …] 仅key存在时在列表右侧插值 | LPUSHX key element [element …] 仅key存在时在列表左侧插值

自2.2.0起可用。

仅当key已经存在并包含列表时,才在key存储的列表尾部或头部插入指定的值。与RPUSHLPUSH相反,当键不存在时,不执行任何操作。

例:RPUSHXLPUSHX同理)

  1. 127.0.0.1:6379> RPUSHX list a
  2. (integer) 0
  3. 127.0.0.1:6379> LRANGE list 0 -1
  4. (empty array)
  5. 127.0.0.1:6379> RPUSH list a
  6. (integer) 1
  7. 127.0.0.1:6379> RPUSHX list a
  8. (integer) 2
  9. 127.0.0.1:6379> LRANGE list 0 -1
  10. 1) "a"
  11. 2) "a"

RPOP key [count] 从列表末尾获取元素并删除 | LPOP key [count] 从列表头部获取元素并删除

自1.0.0起可用。count参数自6.2起可用

删除并返回存储在键值中的列表的最后一个或第一个元素。默认情况下,该命令从列表的末尾或开通弹出一个元素。如果提供了可选的count参数,则返回最多包含count个元素,具体取决于列表的长度。

例:RPOPLPOP同理)

  1. 127.0.0.1:6379> RPUSH a b c d e f
  2. (integer) 5
  3. 127.0.0.1:6379> RPUSH list a b c d e f
  4. (integer) 6
  5. 127.0.0.1:6379> RPOP list
  6. "f"
  7. 127.0.0.1:6379> LRANGE list 0 -1
  8. 1) "a"
  9. 2) "b"
  10. 3) "c"
  11. 4) "d"
  12. 5) "e"
  13. 127.0.0.1:6379> RPOP list 2
  14. 1) "e"
  15. 2) "d"
  16. 127.0.0.1:6379> LRANGE list 0 -1
  17. 1) "a"
  18. 2) "b"
  19. 3) "c"
  20. 127.0.0.1:6379> RPOP list 100
  21. 1) "c"
  22. 2) "b"
  23. 3) "a"

LLEN key 列表长度

自1.0.0起可用

返回存储在键的列表的长度。如果key不存在,它将被解释为一个空列表并返回0。当存储在键的值不是列表时,将返回错误。

  1. 127.0.0.1:6379> RPUSH list a b c
  2. (integer) 3
  3. 127.0.0.1:6379> LLEN list
  4. (integer) 3

LINDEX key index 获取指定索引的值

自1.0.0起可用

返回存储在键的列表中的index处的元素。索引是从零开始的,所以0表示第一个元素,1表示第二个元素,以此类推。负索引可用于指定从列表尾部开始的元素。这里,-1表示最后一个元素,-2表示倒数第二个元素,以此类推。

  1. 127.0.0.1:6379> RPUSH list a b c
  2. (integer) 3
  3. 127.0.0.1:6379> LINDEX list 0
  4. "a"
  5. 127.0.0.1:6379> LINDEX list -1
  6. "c"

LSET key index element 修改指定索引的值

自1.0.0起可用

将索引处的列表元素设置为新元素。对于超出范围的索引将返回一个错误。

  1. 127.0.0.1:6379> RPUSH list a b c
  2. (integer) 3
  3. 127.0.0.1:6379> LRANGE list 0 -1
  4. 1) "a"
  5. 2) "b"
  6. 3) "c"
  7. 127.0.0.1:6379> LSET list 1 world
  8. OK
  9. 127.0.0.1:6379> LRANGE list 0 -1
  10. 1) "a"
  11. 2) "world"
  12. 3) "c"

LREM key count element 删除指定元素

自1.0.0起可用

从key存储的列表中删除与element相等的元素的第一次出现次数。count参数以以下方式影响操作:

  • count > 0:删除等于从头到尾移动的元素。
  • count < 0:删除与从尾部移动到头部相等的元素。
  • count = 0:删除所有等于element的元素。

例如,LREM list -2 "hello"将删除存储在list中的列表中最后两次出现的“hello”。注意,不存在的键被视为空列表,因此当键不存在时,该命令将始终返回0。

  1. 127.0.0.1:6379> RPUSH list hello hello world hello
  2. (integer) 4
  3. 127.0.0.1:6379> LREM list -2 hello
  4. (integer) 2
  5. 127.0.0.1:6379> LRANGE list 0 -1
  6. 1) "hello"
  7. 2) "world"

LTRIM key start stop 裁剪列表

自1.0.0起可用

修改现有列表,使其只包含指定的元素范围。startstop都是从零开始的索引,其中0是列表的第一个元素(头部),1是下一个元素,以此类推。例如:LTRIM foobar 0 2将修改存储在foobar中的列表,以便只保留列表的前三个元素。startend也可以是负数,表示从列表末尾开始的偏移量,其中-1是列表的最后一个元素,-2是倒数第二个元素,以此类推。超出范围的索引不会产生错误:如果start大于列表的末尾,或者start > end,结果将是一个空列表(这将导致键被删除)。如果end大于列表的末尾,Redis会将其视为列表的最后一个元素。

  1. 127.0.0.1:6379> RPUSH list a b c
  2. (integer) 3
  3. 127.0.0.1:6379> LTRIM list 1 -1
  4. OK
  5. 127.0.0.1:6379> LRANGE list 0 -1
  6. 1) "b"
  7. 2) "c"

RPOPLPUSH source destination 从source列表右边吐出一个值,插到destination列表左边

根据Redis 6.2.0,RPOPLPUSH被视为已弃用。请在新代码中使用LMOVE

自1.2.0起可用。

原子式地返回并删除存储在源端的列表的最后一个元素,并将该元素存储在目标端的列表的第一个元素。例如:source包含列表a,b,cdestination包含列表x,y,z。执行RPOPLPUSH的结果是,source变为a,bdestination变为c,x,y,z。如果source不存在,则返回值nil,不执行任何操作。如果源和目标相同,则该操作相当于从列表中删除最后一个元素并将其作为列表的第一个元素压入,因此可以认为它是一个列表旋转命令。

  1. 127.0.0.1:6379> RPUSH list1 a b c
  2. (integer) 3
  3. 127.0.0.1:6379> RPUSH list2 1 2 3
  4. (integer) 3
  5. 127.0.0.1:6379> RPOPLPUSH list1 list2
  6. "c"
  7. 127.0.0.1:6379> LRANGE list1 0 -1
  8. 1) "a"
  9. 2) "b"
  10. 127.0.0.1:6379> LRANGE list2 0 -1
  11. 1) "c"
  12. 2) "1"
  13. 3) "2"
  14. 4) "3"

LMOVE source destination LEFT|RIGHT LEFT|RIGHT 从source移动元素值destination

自6.2.0起可用。

原子式地返回并删除存储在source的列表的第一个/最后一个元素(取决于参数),并将元素存储在destination的列表的第一个/最后一个元素(取决于参数)。如果source不存在,则返回值nil,不执行任何操作。如果sourcedestination相同,则该操作相当于从列表中删除第一个/最后一个元素,并将其作为列表的第一个/最后一个元素推入。

  1. 127.0.0.1:6379> RPUSH list1 a b c
  2. (integer) 3
  3. 127.0.0.1:6379> RPUSH list2 1 2 3
  4. (integer) 3
  5. 127.0.0.1:6379> LMOVE list1 list2 RIGHT RIGHT
  6. "c"
  7. 127.0.0.1:6379> LRANGE list1 0 -1
  8. 1) "a"
  9. 2) "b"
  10. 127.0.0.1:6379> LRANGE list2 0 -1
  11. 1) "1"
  12. 2) "2"
  13. 3) "3"
  14. 4) "c"

LINSERT key BEFORE|AFTER pivot element 插入元素

自2.2.0起可用。

在指定键的列表中的指定值之前或之后的插入元素。当key不存在时,它被认为是一个空列表,不执行任何操作。如果key存在但不包含列表值,则返回错误。该操作返回插入操作后的列表长度,或未找到pivot时返回-1

  1. 127.0.0.1:6379> RPUSH list a b c
  2. (integer) 3
  3. 127.0.0.1:6379> LINSERT list AFTER b 123
  4. (integer) 4
  5. 127.0.0.1:6379> LRANGE list 0 -1
  6. 1) "a"
  7. 2) "b"
  8. 3) "123"
  9. 4) "c"

例:若有多个pivot元素,仅从列表头开始匹配第一个

  1. 127.0.0.1:6379> RPUSH list a b a c
  2. (integer) 4
  3. 127.0.0.1:6379> LINSERT list AFTER a 123
  4. (integer) 5
  5. 127.0.0.1:6379> LRANGE list 0 -1
  6. 1) "a"
  7. 2) "123"
  8. 3) "b"
  9. 4) "a"
  10. 5) "c"

Set 集合

Redis的set对外提供的功能与list类似,是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。Redis的setstring类型的无序集合。它底层其实是一个valuenullhash表,所以添加,删除,查找的复杂度都是O(1)

set数据结构是dict字典,字典是用哈希表实现的。Java中HashSet的内部实现使用的是HashMap,所有的value都指向同一个对象。Redis的set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值。

SADD key member [member …] 添加元素到集合中

自1.0.0起可用。自2.4起,可添加多个元素

将指定的成员添加到存储在键的集合中。已经是该集合成员的指定成员将被忽略。如果key不存在,则在添加指定成员之前创建一个新集合。当存储在键的值不是一个集合时,将返回一个错误。返回值为添加到集合中的元素数,不包括集合中已经存在的所有元素。

  1. 127.0.0.1:6379> SADD set a
  2. (integer) 1
  3. 127.0.0.1:6379> SMEMBERS set
  4. 1) "a"
  5. 127.0.0.1:6379> SADD set b c d
  6. (integer) 3
  7. 127.0.0.1:6379> SMEMBERS set
  8. 1) "b"
  9. 2) "a"
  10. 3) "d"
  11. 4) "c"
  12. 127.0.0.1:6379> SADD set b d e f
  13. (integer) 2
  14. 127.0.0.1:6379> SMEMBERS set
  15. 1) "b"
  16. 2) "f"
  17. 3) "c"
  18. 4) "a"
  19. 5) "e"
  20. 6) "d"

SCARD key 集合大小

自1.0.0起可用。

返回集合的元素个数。

  1. 127.0.0.1:6379> SADD set a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SCARD set
  4. (integer) 3

SMEMBERS key 列出集合中的元素

自1.0.0起可用。

返回存储在键的set值的所有成员。这与运行带有一个参数键的SINTER具有相同的效果。

  1. 127.0.0.1:6379> SADD set a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SMEMBERS set
  4. 1) "b"
  5. 2) "a"
  6. 4) "c"

SISMEMBER key member 存在指定的元素

自1.0.0起可用。

如果member是存储在键值的集合的成员,则返回1,否则返回0

  1. 127.0.0.1:6379> SADD set a
  2. (integer) 1
  3. 127.0.0.1:6379> SISMEMBER set a
  4. (integer) 1
  5. 127.0.0.1:6379> SISMEMBER set b
  6. (integer) 0

SMISMEMBER key member [member …] 存在指定的多个元素

自6.2.0起可用。

返回每个元素是否在集合内。对于每个元素,如果元素在集合内则返回1,如果元素不在集合内或键不存在则返回0

  1. 127.0.0.1:6379> SADD set a
  2. (integer) 1
  3. 127.0.0.1:6379> SMISMEMBER set a b
  4. 1) (integer) 1
  5. 2) (integer) 0

SRANDMEMBER key [count] 随机取出一个或多个元素

自1.0.0起可用。自2.6.0起添加count参数。

  • 当只使用key参数调用时,从集合中随机返回一个随机元素。
  • 如果提供的count参数为正数,则随机返回不超过集合最大个数的count个元素,且没有重复元素。
  • 如果提供的count参数为负数,则随机返回count个元素且允许多次返回相同的元素。
  1. 127.0.0.1:6379> SADD set a b c d e
  2. (integer) 5
  3. 127.0.0.1:6379> SRANDMEMBER set
  4. "e"
  5. 127.0.0.1:6379> SRANDMEMBER set 3
  6. 1) "a"
  7. 2) "e"
  8. 3) "d"
  9. 127.0.0.1:6379> SRANDMEMBER set 8
  10. 1) "b"
  11. 2) "c"
  12. 3) "a"
  13. 4) "d"
  14. 5) "e"
  15. 127.0.0.1:6379> SRANDMEMBER set -3
  16. 1) "b"
  17. 2) "a"
  18. 3) "d"
  19. 127.0.0.1:6379> SRANDMEMBER set -8
  20. 1) "e"
  21. 2) "c"
  22. 3) "c"
  23. 4) "b"
  24. 5) "e"
  25. 6) "e"
  26. 7) "a"
  27. 8) "c"

SPOP key [count] 随机取出一个或多个元素并删除

自1.0.0起可用。自3.2起添加count参数。

从集合中随机移除并返回一个或多个成员。此操作类似于SRANDMEMBER。默认情况下,该命令从集合中弹出一个成员。当提供可选的count参数时,将返回不超过集合最大个数的count个成员。

  1. 127.0.0.1:6379> SADD set a b c d e
  2. (integer) 5
  3. 127.0.0.1:6379> SPOP set
  4. "e"
  5. 127.0.0.1:6379> SPOP set 2
  6. 1) "b"
  7. 2) "a"
  8. 127.0.0.1:6379> SPOP set 5
  9. 1) "d"
  10. 2) "c"

SREM key member [member …] 删除指定元素

自1.0.0起可用。

从集合中删除指定的成员,并返回成功删除的成员数,不属于该集合的指定成员将被忽略。如果key不存在,则将其视为空集,并返回0。当存储在键的值不是一个集合时,将返回一个错误。

  1. 127.0.0.1:6379> SADD set a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SREM set a c e
  4. (integer) 2
  5. 127.0.0.1:6379> SMEMBERS set
  6. 1) "b"

SMOVE source destination member 移动指定元素

自1.0.0起可用。

将指定元素从source集合移动到destination集合。这个操作是原子性的。在每个给定时刻,元素都将显示为其他客户端的源或目标成员。如果source集合不存在或不包含指定的元素,则不执行任何操作并返回0。当指定的元素已经存在于destination集合中时,它只会从source集合中移除。

  1. 127.0.0.1:6379> SADD set1 a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SMOVE set1 set2 a
  4. (integer) 1
  5. 127.0.0.1:6379> SMEMBERS set1
  6. 1) "b"
  7. 2) "c"
  8. 127.0.0.1:6379> SMEMBERS set2
  9. 1) "a"
  10. 127.0.0.1:6379> SMOVE set1 set2 d
  11. (integer) 0

交集 | 并集 | 差集

SINTER key [key …] 交集

自1.0.0起可用。

返回所有给定集合的交集。不存在的键被认为是空集。如果其中一个键是空集,那么结果集也是空的(因为集合与空集的交集总是产生一个空集)。

  1. 127.0.0.1:6379> SADD set1 a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SADD set2 a d f
  4. (integer) 3
  5. 127.0.0.1:6379> SINTER set1 set2
  6. 1) "a"
  7. 127.0.0.1:6379> SINTER set1 set3
  8. (empty array)

SUNION key [key …] 并集

自1.0.0起可用。

返回所有给定集合的并集。不存在的键被认为是空集。

  1. 127.0.0.1:6379> SADD set1 a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SADD set2 a d f
  4. (integer) 3
  5. 127.0.0.1:6379> SUNION set1 set2
  6. 1) "a"
  7. 2) "b"
  8. 3) "f"
  9. 4) "c"
  10. 5) "d"
  11. 127.0.0.1:6379> SUNION set1 set3
  12. 1) "a"
  13. 2) "b"
  14. 3) "c"

SDIFF key [key …] 差集

自1.0.0起可用。

返回所有给定集合的差集。不存在的键被认为是空集。

  1. 127.0.0.1:6379> SADD set1 a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SADD set2 a d f
  4. (integer) 3
  5. 127.0.0.1:6379> SDIFF set1 set2
  6. 1) "b"
  7. 2) "c"
  8. 127.0.0.1:6379> SDIFF set2 set1
  9. 1) "d"
  10. 2) "f"
  11. 127.0.0.1:6379> SDIFF set1 set3
  12. 1) "a"
  13. 2) "b"
  14. 3) "c"

SINTERSTORE destination key [key …] | SUNIONSTORE destination key [key …] | SDIFFSTORE destination key [key …] 计算交并差集并存入目标集合

自1.0.0起可用。

这三个命令等于上文中对应的三个命令,但是它不是返回结果集,而是将结果集即存储在目标集合中,并返回结果集的元素数量。如果目标已经存在,它将被覆盖(注意是覆盖,不是添加)。

  1. 127.0.0.1:6379> SADD set1 a b c
  2. (integer) 3
  3. 127.0.0.1:6379> SADD set2 a d f
  4. (integer) 3
  5. 127.0.0.1:6379> SINTERSTORE dset set1 set2
  6. (integer) 1
  7. 127.0.0.1:6379> SMEMBERS dset
  8. 1) "a"
  9. 127.0.0.1:6379> SUNIONSTORE dset set1 set2
  10. (integer) 5
  11. 127.0.0.1:6379> SMEMBERS dset
  12. 1) "a"
  13. 2) "b"
  14. 3) "f"
  15. 4) "c"
  16. 5) "d"
  17. 127.0.0.1:6379> SDIFFSTORE dset set1 set2
  18. (integer) 2
  19. 127.0.0.1:6379> SMEMBERS dset
  20. 1) "b"
  21. 2) "c"

Hash 哈希散列

Redishash是一个键值对集合。Redishash是一个string类型的fieldvalue的映射表,hash特别适合用于存储对象。类似Java里面的HashMap<String,Object>

Object对象的多种存储方式介绍

有如下Object对象,需要存储到Redis中

  1. User tom1 = new User();
  2. tom.setId(1);
  3. tom.setName("Tom");
  4. tom.setAge(18);

方式1:序列化

tom1作为键,将对象序列化作为值,并使用SET命令存储。

产生问题:每次修改需要先取出反序列化,修改后再序列化并存储,开销较大

方式2:合并字段

tom1和字段合并为键,并字段的值作为值,使用SET存储。

产生问题:部分数据冗余

方式3:散列

tom1作为键,将name等作为字段,将字段的值作为值,使用HSET存储

通过key + field就可以操作对应属性数据,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。

Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable

HSET key field value [field value …] 给键添加字段和值

自2.0.0起可用。

key中的field设置为value。如果key不存在,则创建一个包含散列的新键。如果字段已经存在于散列中,则将覆盖该字段。从Redis 4.0.0开始,HSET是可变的,允许多个field/value。该操作返回添加的字段数。

  1. 127.0.0.1:6379> HSET user name tom age 18
  2. (integer) 2
  3. 127.0.0.1:6379> HGET user name
  4. "tom"
  5. 127.0.0.1:6379> HGET user age
  6. "18"

注:HMSET key field value [field value ...]已弃用,被HSET代替

HSETNX key field value 给键添加字段和值(仅字段不存在)

仅当字段不存在时,将keyfield设置为value。如果key不存在,则创建一个包含散列的新键。如果该field已经存在,则该操作无效。操作成功返回1,失败返回0

  1. 127.0.0.1:6379> HSETNX user name tom
  2. (integer) 1
  3. 127.0.0.1:6379> HSETNX user name tom
  4. (integer) 0
  5. 127.0.0.1:6379> HGET user name
  6. "tom"

HGET key field 获取键的指定字段的值

自2.0.0起可用。

返回与键中的字段相关联的值。当字段不在散列中或键中不存在时返回nil

  1. 127.0.0.1:6379> HSET user name tom age 18
  2. (integer) 2
  3. 127.0.0.1:6379> HGET user name
  4. "tom"
  5. 127.0.0.1:6379> HGET user address
  6. (nil)

HMGET key field [field …] 返回键的多个字段的值

自2.0.0起可用。

返回键中指定字段的值。对于哈希中不存在的字段,将返回一个nil值。因为不存在的键被视为空散列,所以针对不存在的键运行HMGET将返回一个空值列表。

  1. 127.0.0.1:6379> HSET user name tom age 18
  2. (integer) 2
  3. 127.0.0.1:6379> HMGET user name age address
  4. 1) "tom"
  5. 2) "18"
  6. 3) (nil)
  7. 127.0.0.1:6379> HMGET employee name age address
  8. 1) (nil)
  9. 2) (nil)
  10. 3) (nil)

HGETALL key 获取键的所有字段与值

自2.0.0起可用。

返回键的所有字段和值。在返回值中,每个字段名后面都跟着它的值,因此返回的长度是散列大小的两倍。

  1. 127.0.0.1:6379> HSET user name tom age 18
  2. (integer) 2
  3. 127.0.0.1:6379> HGETALL user
  4. 1) "name"
  5. 2) "tom"
  6. 3) "age"
  7. 4) "18"

HEXISTS key field 键是否存在指定字段

自2.0.0起可用。

如果field是键中的现有字段,则返回1,否则返回0

  1. 127.0.0.1:6379> HSET user name tom
  2. (integer) 1
  3. 127.0.0.1:6379> HEXISTS user name
  4. (integer) 1
  5. 127.0.0.1:6379> HEXISTS user age
  6. (integer) 0

HDEL key field [field …] 删除指定键的指定字段

自2.0.0起可用。自2.4起接受多个字段参数。

从键中删除指定的字段,并返回成功删除的字段数。此散列中不存在的指定field将被忽略。如果key不存在,则将其视为空散列,此命令返回0。

  1. 127.0.0.1:6379> HSET user name tom age 18 address shanghai
  2. (integer) 3
  3. 127.0.0.1:6379> HDEL user name age
  4. (integer) 2
  5. 127.0.0.1:6379> HGETALL user
  6. 1) "address"
  7. 2) "shanghai"

HLEN key 键的长度

自2.0.0起可用。

返回键中包含的字段数。键不存在时返回0。

  1. 127.0.0.1:6379> HSET user name tom age 18 address shanghai
  2. (integer) 3
  3. 127.0.0.1:6379> HLEN user
  4. (integer) 3
  5. 127.0.0.1:6379> HLEN employee
  6. (integer) 0

HSTRLEN key field 键的字段的长度

自3.2.0起可用。

返回与键的字段的值的字符串长度。如果该键或字段不存在,则返回0。

  1. 127.0.0.1:6379> HSET user name tom
  2. (integer) 3
  3. 127.0.0.1:6379> HSTRLEN user name
  4. (integer) 3

HKEYS key 键的所有字段 | HVALS key 键的所有值

自2.0.0起可用。

返回键中的所有字段名或所有值。

  1. 127.0.0.1:6379> HSET user name tom age 18 address shanghai
  2. (integer) 3
  3. 127.0.0.1:6379> HKEYS user
  4. 1) "name"
  5. 2) "age"
  6. 3) "address"
  7. 127.0.0.1:6379> HVALS user
  8. 1) "tom"
  9. 2) "18"
  10. 3) "shanghai"

HINCRBY key field increment

自2.0.0起可用。

以增量的方式递增键的字段中的数字。如果键不存在,则创建一个包含散列的新键。如果字段不存在,则在执行操作前将该值设置为0。HINCRBY支持的值范围仅限于64位有符号整数。

  1. 127.0.0.1:6379> HSET user money 10
  2. (integer) 1
  3. 127.0.0.1:6379> HINCRBY user money 5
  4. (integer) 15
  5. 127.0.0.1:6379> HINCRBY user money -20
  6. (integer) -5
  7. 127.0.0.1:6379> HINCRBY user age 18
  8. (integer) 18
  9. 127.0.0.1:6379> HGETALL user
  10. 1) "money"
  11. 2) "-5"
  12. 3) "age"
  13. 4) "18"

Zset 有序集合(Sorted Sets)

Redis的有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复的。因为元素是有序的,所以可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。访问有序集合的中间元素也是非常快的,因此能够使用有序集合作为一个没有重复成员的智能列表。

Sorted Set (Zset)Redis提供的一个非常特别的数据结构,一方面它等价于Java的数据结构Map<String, Double>,可以给每一个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。

zset底层使用了两个数据结构

  1. hashhash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
  2. 跳跃表跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。

有序集合在生活中比较常见,例如根据成绩对学生排名,根据得分对玩家排名等。对于有序集合的底层实现,可以用数组、平衡树、链表等。数组不便元素的插入、删除;平衡树或红黑树虽然效率高但结构复杂;链表查询需要遍历所有效率低。Redis采用的是跳跃表。跳跃表效率堪比红黑树,实现却比红黑树简单。

对比有序链表和跳跃表,从链表中查询出51

要查找值为51的元素,需要从第一个元素开始依次查找、比较才能找到。共需要6次比较。

  1. 从第2层开始,1节点比51节点小,向后比较。21节点比51节点小,继续向后比较,后面就是NULL了,所以从21节点向下到第1层
  2. 在第1层,41节点比51节点小,继续向后,61节点比51节点大,所以从41向下
  3. 在第0层,51节点为要查找的节点,节点被找到,共查找4次。

从此可以看出跳跃表比有序链表效率要高

ZADD key score member 将一个或多个member及source添加到排序集合中

ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]

自1.2.0起可用。
自2.4起,接受多个元素。
自3.0.2起,增加了XX,NX,CH和INCR选项。
自6.2起,添加了GT和LT选项。

将具有指定分数的所有指定成员添加到排序集合。可以指定多个score / member对。如果指定的成员已经是排序集合的成员,则更新score并将元素重新插入到正确的位置,以确保正确的排序。如果key不存在,将创建一个新的排序集合,其中指定的成员作为唯一的成员,就像排序集为空一样。如果键存在,但不是排序集合,则返回错误。分数值应该是双精度浮点数的字符串表示形式。+inf-inf值也是有效值。

ZADD支持一个选项列表,在键名之后和第一个score参数之前指定。选项有:

  • XX:只更新已经存在的元素。没有添加元素。
  • NX:不要更新已经存在的元素。总是添加新元素。
  • LT:只有当新分数小于当前分数时才更新现有的元素。这个标志并不阻止添加新元素。
  • GT:只有当新分数大于当前分数时才更新现有的元素。这个标志并不阻止添加新元素。
  • CH:将返回值从添加的新元素数量修改为更改的总元素数量(CH是changed的缩写)。改变的元素是指添加的新元素和已经存在并更新了分数的元素。因此,在命令行中指定的具有与过去相同分数的元素将不被计算。注意:通常ZADD的返回值只计算添加的新元素的数量。
  • INCR:当指定此选项时,ZADD的行为类似于ZINCRBY。在此模式中只能指定一个分数元素对。

注:GTLTNX选项是互斥的。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZRANGE zset 0 -1 WITHSCORES
  4. 1) "english"
  5. 2) "60"
  6. 3) "chinese"
  7. 4) "80"
  8. 5) "maths"
  9. 6) "90"

ZRANGE key min max 返回排序集合中的指定范围的元素

ZRANGE key min max [BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES]

自1.2.0起可用。

返回存储在的排序集合中指定的元素范围。ZRANGE可以执行不同类型的范围查询:按索引(排名)、按分数或按字典序。

  • 常见行为和选项:
    • 元素的顺序从最低到最高。得分相同的元素按字典顺序排列。
    • 可选的REV参数颠倒了顺序,因此元素按从最高到最低的分数排序,而分数关系则通过反向字典序来解析。
    • 可选的LIMIT参数可用于从匹配的元素中获取子范围(类似于SELECT LIMIT offset, count在SQL中)。负数返回<偏移量>中的所有元素。请记住,如果<偏移量>的偏移量较大,则需要遍历<偏移量>的元素,然后才能返回返回的元素,这可能会增加O(N)的时间复杂度。
    • 可选的WITHSCORES参数用返回的元素的分数补充命令的应答。返回的列表包含value1,score1,…,valueN,scoreN代替value1,…,valueN。客户端库可以自由返回更合适的数据类型(建议:包含(value, score)数组/元组的数组)。
  • 索引范围:
    • 缺省情况下,执行索引范围查询。和参数表示从零开始的索引,其中0是第一个元素,1是下一个元素,以此类推。这些参数指定了一个包含范围,因此,例如,ZRANGE myzset 0 1将返回排序集合的第一个和第二个元素。
    • 索引也可以是负数,表示从排序集的末尾开始的偏移量,其中-1是排序集的最后一个元素,-2是倒数第二个元素,以此类推。
    • 超出范围的索引不会产生错误。
    • 如果大于排序集合的结束索引或,则返回一个空列表。
    • 如果大于排序集合的结束索引,Redis将使用排序集合的最后一个元素。
  • 分数范围
    • 当提供BYSCORE选项时,该命令的行为类似于ZRANGEBYSCORE,并返回分值等于或介于和之间的排序集合中的元素范围。
    • 和可以是-inf和+inf,分别表示负无穷和正无穷。这意味着不需要知道排序集合中的最高或最低分数才能获得从某个分数开始的或到某个分数为止的所有元素。
    • 默认情况下,和指定的评分间隔是封闭的(包括在内)。可以通过在分数前加上字符(/)来指定开放间隔(不包括)。
  • 辞典范围
    • 当使用BYLEX选项时,该命令的行为类似于ZRANGEBYLEX,并返回排序集合中和字典序封闭范围间隔之间的元素范围。
    • 请注意,字典顺序依赖于所有得分相同的元素。当元素有不同的分数时,应答是未指定的。
    • 有效的和必须以(或[开头,以便分别指定范围间隔是exclusive还是inclusive。
    • 特殊值+或- 和分别表示正的和负的无限字符串,所以例如命令ZRANGEBYLEX myzset - +保证返回排序集合中的所有元素,前提是所有元素的得分相同。

注:以下命令在Redis 6.2.0被弃用,均被ZRANGE替代

  • ZREVRANGE key start stop [WITHSCORES]
  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
  • ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
  • ZRANGEBYLEX key min max [LIMIT offset count]
  • ZREVRANGEBYLEX key max min [LIMIT offset count]
  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZRANGE zset 0 -1
  4. 1) "english"
  5. 2) "chinese"
  6. 3) "maths"
  7. 127.0.0.1:6379> ZRANGE zset 0 -1 WITHSCORES
  8. 1) "english"
  9. 2) "60"
  10. 3) "chinese"
  11. 4) "80"
  12. 5) "maths"
  13. 6) "90"

ZRANGESTORE dst src min max 查找排序集合中的指定范围的元素并存入目标排序集合

ZRANGESTORE dst src min max [BYSCORE|BYLEX] [REV] [LIMIT offset count]

自6.2.0起可用。

此命令类似于ZRANGE,但是将结果存储在<dst>目标键中。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZRANGESTORE zset2 zset 1 -2
  4. (integer) 1
  5. 127.0.0.1:6379> ZRANGE zset2 0 -1
  6. 1) "chinese"

ZCARD key 返回排序集合的元素数量

自1.2.0起可用。

返回存储在的排序集的排序集基数(元素数)key。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZCARD zset
  4. (integer) 3

ZCOUNT key min max 统计指定范围内的元素数量

自2.0.0起可用。

返回排序集合中键值在minmax之间的元素数。min和max参数具有与ZRANGE描述的相同的语义。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZCOUNT zset -inf +inf
  4. (integer) 3

ZSCORE key member 返回排序集中key的分数

自1.2.0起可用。

返回排序集合中成员的得分。如果成员不存在于排序集合中,或者键不存在,则返回nil。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZSCORE zset chinese
  4. "80"
  5. 127.0.0.1:6379> ZMSCORE zset chinese maths history
  6. 1) "80"
  7. 2) "90"
  8. 3) (nil)

ZMSCORE key member [member …] 返回排序集中key的分数(多个key)

自6.2.0起可用。

返回排序集合中多个成员和其相关联的分数。对于排序集合中不存在的每个成员,将返回一个nil值。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZMSCORE zset chinese maths history
  4. 1) "80"
  5. 2) "90"
  6. 3) (nil)

ZRANK key member | ZREVRANK key member 正序或倒序排名

自2.0.0起可用。

返回排序集合中的成员的排名,分数按从低到高或从高到低的顺序排序。排名(或索引)是从0开始,这意味着得分最低或最高的成员排名为0。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZRANK zset maths
  4. (integer) 2
  5. 127.0.0.1:6379> ZREVRANK zset maths
  6. (integer) 0

ZINCRBY key increment member 给指定元素增减分数

自1.2.0起可用。

按增量递增排序集合中的成员的得分,并返回成员的新分数(双精度浮点数),表示为字符串。如果成员在排序集合中不存在,则将其添加为增量作为其分数(就像其以前的分数是0.0)。如果key不存在,则创建一个新的排序集合,其中指定的成员作为其唯一成员。如果键存在但不是排序集合,则返回错误。分数值应该是数字值的字符串表示形式,并接受双精度浮点数。可以提供一个负值来减少分数。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZINCRBY zset 12.5 chinese
  4. "92.5"

ZREM key member [member …] 删除元素

自1.2.0起可用。自2.4起接受多个元素。

从排序集合中删除指定成员,并返回移除的成员数,不存在的成员将被忽略。如果键存在但不是排序集合,则返回错误。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZREM zset chinese history
  4. (integer) 1
  5. 127.0.0.1:6379> ZRANGE zset 0 -1
  6. 1) "english"
  7. 2) "maths"

ZPOPMAX key [count] | ZPOPMIN key [count] 删除并返回多个分数最大或最小的元素

自5.0.0起可用。

删除并返回排序集合中得分最高或最低的成员。当未指定时,count的默认值是1。指定一个大于排序集合总数量的数值将不会产生错误。当返回多个元素时,得分最高或最低的元素将是第一个,然后是得分较低或较高的元素。

例:ZPOPMAX

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZPOPMAX zset 3
  4. 1) "maths"
  5. 2) "90"
  6. 3) "chinese"
  7. 4) "80"
  8. 5) "english"
  9. 6) "60"

例:ZPOPMIN

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 english
  2. (integer) 3
  3. 127.0.0.1:6379> ZPOPMIN zset 3
  4. 1) "english"
  5. 2) "60"
  6. 3) "chinese"
  7. 4) "80"
  8. 5) "maths"
  9. 6) "90"

ZRANDMEMBER key [count [WITHSCORES]] 随机返回元素

自6.2.0起可用。

当仅使用key参数调用时,从排序集合中返回一个随机元素。如果提供的count参数为正数,则返回一个包含不同元素的数组。数组的长度可以是count,也可以是排序集合的基数(ZCARD),两者以较低者为准。如果以负数计数调用,则行为会改变,并且允许命令多次返回相同的元素。可选的WITHSCORES修饰符更改应答,使其包含从排序集合中随机选择的元素的各自分数。

  1. 127.0.0.1:6379> ZADD zset 80 chinese 90 maths 60 englis
  2. (integer) 3
  3. 127.0.0.1:6379> ZRANDMEMBER zset 2
  4. 1) "chinese"
  5. 2) "englis"
  6. 127.0.0.1:6379> ZRANDMEMBER zset 5 WITHSCORES
  7. 1) "maths"
  8. 2) "90"
  9. 3) "chinese"
  10. 4) "80"
  11. 5) "englis"
  12. 6) "60"
  13. 127.0.0.1:6379> ZRANDMEMBER zset -1 WITHSCORES
  14. 1) "chinese"
  15. 2) "80"
  16. 127.0.0.1:6379> ZRANDMEMBER zset -5 WITHSCORES
  17. 1) "chinese"
  18. 2) "80"
  19. 3) "chinese"
  20. 4) "80"
  21. 5) "chinese"
  22. 6) "80"
  23. 7) "englis"
  24. 8) "60"
  25. 9) "englis"
  26. 10) "60"

补充:原子性

所谓原子操作是指:不会被线程调度机制打断的操作

这种操作一旦开始,就一直运行到结束,中间不会有任何context switch(切换到另一个线程)。

  1. 在单线程中,能够在单条指令中完成的操作都可以认为是“原子操作”,因为中断只能发生于指令之间。
  2. 在多线程中,不能被其它进程(线程)打断的操作就叫原子操作。

Redis单命令的原子性主要得益于Redis的单线程。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK