Redis散列表(hash)使用

Redis有5种常用的数据结构,分别为:string(字符串),list(列表),hash(哈希表或散列表),set(集合)和zset(有序集合)。5种数据结构指的是作为键值对的值存在于Redis库中的形态,顾名思义,string字符串的value值是以字符串结构存在的;hash散列表的value是一个hash散列表。

散列表简单说明

Redis的散列(hash)表会将一个键和一个散列表在数据库中关联起来,用户可以在散列表中为任意多个字设置值。与字符串键值对一样,散列表里面的字段和值既可以是文本数据,可以是二进制数据。

通过使用散列表,用户可以把相关联的多项数据存储到同一个散列里面,以便对这些数据进行管理,或者针对他们进行批量操作。

上图可以看到,字符串键值对的值是一个单字符串形态的存在;而散列表的value值是一个散列表,或称为哈希表,散列表内部的字段和值对照关系就与字符串的键值对类似了。

Redis为散列舰提供了一系列操作命令,通过这些命令用户可以:

  • 为散列的字段设置值,或者只在字段不存在的情况下为他设置值从散列表里面获取给定字段的值。
  • 对存储着数字值的字段执行加法操作或者减法操作。
  • 检查给定字段是否存在于散列表当中。
  • 从散列表中删除指定字段。
  • 查看散列表包含的字段数量。
  • 一次为散列表的多个字段设置值或一次从散列表中获取多个字段的值。
  • 获取散列表包含的所有字段,所有值或者所有字段和值。

散列表命令说明

hset:为字段设置值

用户可以通过执行hset命令为散列表中的指定字段设置值。

hset key field value

根据给定的字段是否已经存在于散列中命令的执行也会有所不同:

  • 如果给定字段并不存在于散列当中,那么这次设置就是一次创建操作命令,将在散列里面关联起给定的字段和值,然后返回1。
  • 如果给定的字段原本已经存在于散列当中,那么这次设置就是一次更新操作命令,将使用用户给定的新值去覆盖字段原有的旧址,然后返回0。

上图示例可以看到,在给student_zhangsan第一次设置age字段为14时,因为散列表中没有age字段,字段age属于第一次创建,命令执行完成后返回的是1;待第二次给age再设置值为16时,因为age已经存在于散列表中,命令执行时候,新的字段值16会覆盖掉旧的字段值14,并返回0。


hsetnx:只在字段不存在的情况下为它设置值

hsetnx命令的作用和hset命令的作用非常相似,都是给散列表的字段设置值。他们的不同之处在于,hsetnx命令只会在指定字段不存在的情况下执行设置操作。

hsetnx key field value

hsetnx命令在字段不存在并且设置成功时返回值1;在字段存在并导致设置失败时返回值0。


hget:获取字段的值

hget命令可以根据用户给定的字段,从散列表中获取该字段的值。

hget key field

如果给定的字段并不存在于散列表中,那么hget命令将返回一个空值

通过hkeys命令,可以获取到散列表的所有字段名称,再通过hget去获取一个不存在的字段birthday的值,因散列表中没有该字段,返回为nil。

如果散列表本身就不存在的时候,我们再去获取字段值,会发生什么事情

通过上面的示例可以看出,当hget获取结果为nil时,有两种情况:

  • 散列表中该字段不存在
  • 散列表本身不存在

hincrby:对字段存储的整数值执行加减法操作

与字符串的incrby命令相似,如果散列表的字段里面存储的能够被Redis解释为整数的数字,那么用户就可以使用hincrby命令为该字段的值加上指定的增量。

hincrby key field increment

hincrby命令操作成功后,会返回该字段当前值作为结果。

与字符串数值加法有decrby命令不同的是,散列表没有对对应字段做减法操作的命令。即如果要对散列表的数字值操作减法,使用hincrby命令,并将增量increment值设置为负值即可。

同时,字符串里面有增量加1的默认命令incr,在散列表中没有了,对于散列表的增减值都只能用hincrby命令,并根据自己的须要设置合适的增量值increment。

如果对散列表中非整数的字段使用hincrby 或 增量值increment非整数的时候,会有什么结果

示例可以看到:

  • hincrby student_zhangsan age 1.2 对age字段增加1.2的时候,因1.2非整数值,报错(error) ERR value is not an integer or out of range
  • hincrby student_zhangsan addr 1 对zddr字段加1的时候,因addr字段值为字符串"beijing",无法解析为数字,报错(error) ERR hash value is not an integer

hincrbyfloat:对字段存储的数字值执行浮点加减法操作

hincrbyfloat命令作用与hincrby命令作用类似,hincrby是对字段值为整数的字段进行整数增量值的操作,hincrbyfloat命令可以对整数和浮点数的字段值进行操作,且增量值可以是整数可以是浮点数。与hincrby命令类似,hincrbyfloat命令没有对应的减法命令,如果要操作减法,即要对增量值做负数处理。

hincrbyfloat key field increment

hincrbyfloat命令在执行成功后,将返回给定字段值当前值作为结果

上面示例,展示了hincrbyfloat命令给浮点数增加浮点数值,给整数增加浮点数值。

上面示例,展示hincrbyfloat命令的减法操作,给增量increment字段赋负值。

示例中,前面的score均为浮点数,都是在用hincrbyfloat命令做操作,在执行hincrbyfloat student_zhangsan score -0.5后,score值变为了87,后面使用hincrby命令对score字段值操作成功。说明,散列表操作中,字段值若从浮点数变化为整数的时候,系统中默认按照整数存储。


hstrlen:获取字段值的字节长度

用户可以使用hstrlen命令获取给定字段值的字节长度

hstrlen key field

示例的时候尴尬了,提示hstrlen命令不存在,翻阅了资料发现,hstrlen命令是Redis在3.2.0版本加进来的

而目前使用的Windows版的Redis是3.0.503版本的。

hstrlen命令的用法与字符串对应的strlen类似,可以参考前一篇博文Redis字符串键值对使用中关于strlen命令部分。

hstrlen命令在对于散列表中不存在的字段操作时候,返回0;hstrlen对不存在的散列表操作时候,返回0。


hexists:检查字段是否存在

hexists命令用于检查用户给定的字段是否存在于散列表中

hexists key field

如果散列表中包含了给定的字段filed,则命令返回1,否则命令返回0。

上面示例,可以看到name是student_zhangsan中存在的字段,使用hexists命令操作返回1;对于不存在的字段youreyes命令操作时候返回0;对于不存在的散列表not-exists-hash操作返回0。

同样说明,如果hexists命令结果为0,可能有两种情况:

  • 散列表中字段不存在
  • 散列表不存在

hdel:删除字段

hdel命令用于删除散列表中指定字段极其对应的关联值

hdel key field

当给定的字段存在于散列表中并且被成功删除的时候,命令返回1;如果给定的字段不存在散列表中,或者给定的散列表不存在的时候,命令返回0。

上面示例,name字段存在于student_zhangsan中,执行hdel命令后,命令返回1,再通过hget获取name字段,返回空值nil

上面示例,展示hdel删除散列表中不存在的字段,和hdel操作不存在的散列表情况,结果都是删除失败,返回0。

上面说的是hdel命令删除散列表中三个字段值的情况,hdel命令可以删除多个字段值

hdel key field1 field2 ... fieldn

hdel命令删除多个字段值的时候,命令结果返回删除成功的字段的个数。若字段都不存在或散列表不存在,则返回0。

上图示例,散列表student_zhangsan中包含addr、score、id、name和age五个字段,使用hdel student_zhangsan name age youreyes 来删除字段name age youreyes,其中name和age是散列表student_zhangsan中存在的字段,youreyes是散列表中不存在的字段。执行hdel命令后,成功删除name和age两个字段和其对应的值,命令返回删除成功的字段的个数2。

上图示例,展示操作完全不存在的字段和操作不存在的散列表的情况,结果都是0。


hlen:获取散列表包含的字段数量

hlen命令获取给定的散列表的字段数量,命令返回结果为散列表中包含的字段数量

hlen key field

如果对不存在的散列表执行hlen命令,结果为0。


hmset:一次为多个字段设置值

hset命令一次只可以为一个字段设置值,hmset命令一次为散列表的多个字段设置值,hset命令在设置成功时返回OK。

hmset key field value [field value ...]

上面示例,展示了hmset的用法,且与hset做了个简单比对。假如我们要给散列表中设置4个字段值进去,使用hset命令须要操作4次,即客户端与Redis服务器有4次通信交互;使用hmset只须要一次即可完成,这里节省了3次通信交互的消耗。所以,在给散列表设置多个字段值的时候,使用hmset是比较高效的。

上面命令中,我们的字段值都是单字符串,如果是句子或字符串中有空格呢,试试

上面示例,第一次使用hmset设置hmset db_book3 book1 redis is book1,这里的原意是字段book1的值为redis is book1,设置成功。再通过hmset 设置 hmset db_book3 book1 redis is book1,多设置一个book2字段进去,设置成功。通过hlen命令查看字段数量时候,发现数量是3。通过hgetall命令获取所有字段和值,得到三个字段和对应值。

这里的问题,由于value值没有加双引号“" "”,系统默认按照空格把每一个词按照字段-值-字段-值的方式处理了,如果value中间有空格时候,value值一定要用双引号引起来。


hmget:一次获取多个字段的值

通过hmget命令,用户可以一次从散列表中获取多个字段的值

hmget key field [field ...]

执行hmget命令后,结果字段顺序,依次返回字段对应的值,对于不存在的字段,返回空值nil。


hkeys、hvals、hgetall:获取所有字段、所有值、所有字段和值

hkeys命令,返回散列表中所有的字段名称

hkeys key

hvals命令,返回散列表中所有的字段对应的值

hvals key

hgetall结合hkeys和hvalues两个命令的作用,返回散列表中所有的字段名称和对应的值

hgetall key

hgetall命令返回结果列表中,每两个连续的元素代表了散列表中的一对字段和值,其中奇数位置上的元素为字段,偶数位置上的元素为字段的值。


散列表使用总结

1、散列键会将一个键和一个散列在数据库中关联起来,用户可以在散列中为任意多个字段设置值与字符串键一样散列的字段和值,既可以是文本数据也可以是二进制数据。

2、用户可以通过散列键,把相关联的多项数据存储到同一散列中,以便对其进行管理,或者针对他们执行批量操作。

3、因为Redis并没有为散列提供相应的减法操作命令,所以如果用户想要对字段存储的数字值进行减法操作,需要将负数增长量传递给命令。

4、Redis散列包含的字段在底层是以无序方式存储的,根据字段插入的顺序不同,包含相同字段的散列在执行等命令时可能会得到不同的结果,因此用户在使用这三个命令时,不应该对命令返回元素的排列顺序,做任何假设。

猜你喜欢

转载自blog.csdn.net/magi1201/article/details/113662385