redis数据结构之hash
请看官方文档:redis中文官方文档
-
哈希表
Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口,也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。
这里同时需要注意,Redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部Map的操作,由于Redis单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意。
实现方式:(2种不同实现)
- Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,大家对数组应该比较了解,数组是通过索引快速定位到指定元素的,无论是访问数组的第一个元素还是最后一个元素,所耗费的时间都是一样的,但是数组中的索引却没有实际意义,他只是一个位置而已。而我们在查找某个元素时,一般都会使用有意义的字段来做索引,这就产生啦dictionary。其实dictionary的实现,就是让key跟下标索引有一定的关系,所实现的,让他的查找算法复杂度变为常数O(1);
- 当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
总结:
- hash⽤于存储对象,对象的结构为属性(field)、值(value)
- 值的类型为string
-
常见命令
-
hset
语法:hset hash field value
介绍:
- 如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行
HSET
操作。 - 如果域
field
已经存在于哈希表中, 那么它的旧值将被新值value
覆盖。
返回值:
- 当
HSET
命令在哈希表中新创建field
域并成功为它设置值时, 命令返回1
; - 如果域
field
已经存在于哈希表, 并且HSET
命令成功使用新值覆盖了它的旧值, 那么命令返回0
- 如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行
-
hsetnx
语法:hsetnx hash field value
介绍:
- 当且仅当域
field
尚未存在于哈希表的情况下, 将它的值设置为value
。 - 如果给定域已经存在于哈希表当中, 那么命令将放弃执行设置操作。
- 如果哈希表
hash
不存在, 那么一个新的哈希表将被创建并执行HSETNX
命令。
返回值:
HSETNX
命令在设置成功时返回1
, 在给定域已经存在而放弃执行设置操作时返回0
。 - 当且仅当域
-
hget
语法:hget hash field
介绍:返回哈希表中给定域的值。
返回值:
HGET
命令在默认情况下返回给定域的值。- 如果给定域不存在于哈希表中, 又或者给定的哈希表并不存在, 那么命令返回
nil
。
-
hexisis
语法:hexisis hash field value
介绍:检查给定域
field
是否存在于哈希表hash
当中。返回值:
HEXISTS
命令在给定域存在时返回1
, 在给定域不存在时返回0
。 -
hdel
语法:hdel key field [field …]
介绍:删除哈希表
key
中的一个或多个指定域,不存在的域将被忽略。**返回值:**被成功移除的域的数量,不包括被忽略的域。
-
hlen
语法:hlen key
介绍:返回哈希表
key
中域的数量。**返回值:**哈希表中域的数量,当
key
不存在时,返回0
。 -
hstrlen
语法:hstrlen key filed
介绍:返回哈希表
key
中, 与给定域field
相关联的值的字符串长度(string length),如果给定的键或者域不存在, 那么命令返回0
。**返回值:**一个整数
-
hincrby
语法:hincrby key filed increment
介绍:为哈希表
key
中的域field
的值加上增量increment
,增量也可以为负数,相当于对给定域进行减法操作。如果key
不存在,一个新的哈希表被创建并执行 HINCRBY 命令,如果域field
不存在,那么在执行命令前,域的值被初始化为0
。对一个储存字符串值的域field
执行 HINCRBY 命令将造成一个错误,本操作的值被限制在 64 位(bit)有符号数字表示之内。**返回值:**哈希表
key
中域field
的值。 -
hincrbyfloat
语法:hincrbyfloat key field increment
介绍:为哈希表
key
中的域field
加上浮点数增量increment
。如果哈希表中没有域field
,那么 HINCRBYFLOAT 会先将域field
的值设为0
,然后再执行加法操作。如果键key
不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域field
,最后再执行加法操作。**返回值:**执行加法操作之后
field
域的值。 -
hmset
语法:hmset key field value [field value …]
介绍:同时将多个
field-value
(域-值)对设置到哈希表key
中。此命令会覆盖哈希表中已存在的域。如果key
不存在,一个空哈希表被创建并执行 HMSET 操作。**返回值:**如果命令执行成功,返回
OK
。当key
不是哈希表(hash)类型时,返回一个错误。 -
hmget
语法:hmget key field [field …]
介绍:返回哈希表
key
中,一个或多个给定域的值。如果给定的域不存在于哈希表,那么返回一个nil
值。因为不存在的key
被当作一个空哈希表来处理,所以对一个不存在的key
进行 HMGET 操作将返回一个只带有nil
值的表。**返回值:**一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。
-
hkeys
语法:hkeys key
介绍:返回哈希表
key
中的所有域。**返回值:**一个包含哈希表中所有域的表。当
key
不存在时,返回一个空表。 -
hvals
语法:hvals key
介绍:返回哈希表
key
中所有域的值。**返回值:**一个包含哈希表中所有值的表。当
key
不存在时,返回一个空表。 -
hgetall
语法:hgetall key
介绍:返回哈希表
key
中,所有的域和值。在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。**返回值:**以列表形式返回哈希表的域和域的值。若
key
不存在,返回空列表。
-