当前位置:首页 > 问答 > 正文

Redis里那些查对象的命令,快速搞定查询其实没那么难

基于对Redis官方文档及常见使用实践的归纳)

说到在Redis里查东西,很多人第一反应可能就是GETSET,觉得这有啥难的,确实,如果只是对付简单的键值对,这两个命令就够了,但Redis的能力远不止于此,它有好几种数据结构,比如大家常说的列表(List)、集合(Set)、有序集合(Sorted Set)和哈希(Hash),每种结构都有自己的“专属”查询命令,用对了才能真的“快速搞定”,今天就不绕弯子,直接把这些查对象的命令捋一捋,让你心里有个数。

最基础的,你得知道你要查的键存不存在,这时候别急着GET,万一它存的不是字符串呢?或者万一它根本不存在呢?先上EXISTS命令探探路,比如EXISTS user:1001,返回1就表示这个键存在,返回0就是不存在,这就像你去朋友家敲门,先听听里面有没有动静,免得白费力气。

确认键存在之后,你最好再用TYPE命令看看它到底是什么类型。TYPE user:1001可能会返回stringhashlist等等,知道类型了,你才能选用正确的工具,不然就像用螺丝刀去拧螺母,不是不行,但很别扭,还容易坏。

Redis里那些查对象的命令,快速搞定查询其实没那么难

好,现在咱们就分门别类地看看怎么查。

第一类:查简单的字符串值(String) 这个最简单,就是GET key,比如你存了个SET website "redis.com",那GET website就直接给你返回"redis.com",如果你想一次查多个键,可以用MGET key1 key2 key3,这样能减少网络来回的次数,效率更高。

第二类:查哈希对象(Hash) 哈希特别适合存一个对象,比如一个用户的信息,你可能用HSET user:1001 name "张三" age 30 city "北京"存了一堆字段,查的时候就有几种玩法:

Redis里那些查对象的命令,快速搞定查询其实没那么难

  1. 查单个字段:HGET user:1001 name,这就返回"张三"。
  2. 查多个字段:HMGET user:1001 name age,返回"张三"和"30"。
  3. 查所有字段和值:HGETALL user:1001,这会把这个哈希里所有的东西都给你翻出来,返回是name张三age30city北京这样的列表,如果这个哈希字段非常多,用这个命令要小心,可能会一下子返回大量数据。
  4. 只查所有字段名:HKEYS user:1001,返回nameagecity
  5. 只查所有字段值:HVALS user:1001,返回"张三"、"30"、"北京"。
  6. 查字段个数:HLEN user:1001,返回3。

你看,针对哈希这种结构,Redis给了你很多种“抓手”,想查哪部分就查哪部分。

第三类:查列表(List) 列表就像排队,数据一个接一个,你可能会用LPUSHRPUSH往里塞数据,查的时候:

  1. 按索引查单个元素:LINDEX mylist 0,查第一个元素(索引从0开始)。LINDEX mylist -1则查最后一个元素。
  2. 查一段范围内的元素:这是最常用的LRANGE命令,比如LRANGE mylist 0 2,就把前三个元素查出来。LRANGE mylist 0 -1就更厉害了,直接把整个列表都给你搬出来,这个命令在分页查看数据时特别有用。
  3. 查列表长度:LLEN mylist,告诉你列表里有多少个元素。

第四类:查集合(Set) 集合里的元素是无序且不重复的,主要用来判断成员关系或者求交集并集啥的,查询方面:

Redis里那些查对象的命令,快速搞定查询其实没那么难

  1. 判断元素是否在集合中:SISMEMBER myset "hello",在就返回1,不在返回0,这招很快。
  2. 获取集合所有成员:SMEMBERS myset,和HGETALL类似,如果集合很大,这个命令也会返回很多数据,要谨慎使用。
  3. 查集合元素个数:SCARD myset
  4. 随机获取一个或多个成员:SRANDMEMBER myset或者SRANDMEMBER myset 2(获取2个),这个不删除元素。
  5. 求集合间的差集、交集、并集:SDIFF set1 set2SINTER set1 set2SUNION set1 set2,这些命令在需要对比多组数据时非常强大。

第五类:查有序集合(Sorted Set) 这是带分数的集合,可以根据分数排序,查询花样最多:

  1. 按分数范围查:ZRANGEBYSCORE players 1000 2000,查分数在1000到2000之间的成员,还可以加上WITHSCORES选项把分数也带出来。
  2. 按排名查:ZRANGE players 0 2 查排名前三的(从低到高),ZREVRANGE players 0 2查排名前三的(从高到低),同样可以加WITHSCORES
  3. 查某个成员的分数:ZSCORE players "playerA"
  4. 查某个成员的排名:ZRANK players "playerA"(从低到高排名),ZREVRANK players "playerA"(从高到低排名)。
  5. 查集合元素个数:ZCARD players
  6. 统计分数区间内的成员数:ZCOUNT players 1000 2000

第六类:通配符查找键名 有时候你记不住完整的键名,或者想批量操作一类键,可以用KEYS命令,比如KEYS user:*就能找出所有以user:开头的键。但是要特别注意KEYS命令在生产环境要极度小心,因为它会遍历数据库里所有的键,如果数据量巨大,这个命令可能会让Redis暂时卡住,影响其他操作,一个更安全的替代方案是使用SCAN命令,它可以增量式地迭代遍历,不会阻塞服务太久。

最后的小贴士 查数据的时候,脑子里要有个大概印象:你存的是什么结构,就用什么命令去查。GET一个哈希键是没结果的,HGET一个字符串键也会报错,多用TYPE命令能帮你避免这种尴尬。

Redis 6.0.0之后还给一些命令加了EX选项,比如GETEX,可以在获取值的同时修改它的过期时间,一举两得,也挺方便的。

Redis查对象真的不难,核心就是“对症下药”,把这些命令当成你工具箱里不同的工具,需要拧螺丝的时候拿扳手,需要钉钉子的时候用锤子,平时多练练手,熟悉了之后,查询操作自然就能又快又准了,希望这些直接的介绍能帮你更快地上手Redis的查询。