介绍
Redis是采用字典结构以键值对的形式存储数据的,而散列类型(hash) 的键值也是一种字典结构,其存储了字段(field)和字段值的映射,但字段值只能是字符串,不支持其他数据类型,也就是说散列类型不能嵌套其他的数据类型。一个散列类型键可以包含至多2^32-1个字段。除了散列类型,Redis的其他数据类型同样不支持数据类型嵌套。比如集合类型的每个元素都只能是字符串,不能是另一个集合或散列表等。
一、hash类型特点
哈希键值结构:
特点:
map中的map
field不能相同,value可以相同
减少了redis维护的key的数据,比较轻盈
获取维度值方便
将耗时的业务数据单独放在一台redis实例上
拆分不同的redis实例,存储不同的业务数据将业务请求分割
二、应用场景散列类型适合存储对象:使用对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。例如要存储ID为1的汽车对象,可以分别使用名为color、name和price的3个字 段来存储该辆汽车的颜色、名称和价格。存储结构如下:
场景一:记录网站每个用户个人主页的访问量
hincrby user:1:info pageview count
场景二:缓存数据
Map hashMap = redis.hgetAll(redisKey);UserInfo userInfo = transferMapToUserInfo(hashMap);
hgetAll会返回redis中对应key的所有数据,当数据量太大的时候谨慎使用
三、命令拾遗
127.0.0.1:6379> help @hash HDEL key field [field ...] summary: Delete one or more hash fields since: 2.0.0 HEXISTS key field summary: Determine if a hash field exists since: 2.0.0 HGET key field summary: Get the value of a hash field since: 2.0.0 HGETALL key summary: Get all the fields and values in a hash since: 2.0.0 HINCRBY key field increment summary: Increment the integer value of a hash field by the given number since: 2.0.0 HINCRBYFLOAT key field increment summary: Increment the float value of a hash field by the given amount since: 2.6.0 HKEYS key summary: Get all the fields in a hash since: 2.0.0 HLEN key summary: Get the number of fields in a hash since: 2.0.0 HMGET key field [field ...] summary: Get the values of all the given hash fields since: 2.0.0 HMSET key field value [field value ...] summary: Set multiple hash fields to multiple values since: 2.0.0 HSCAN key cursor [MATCH pattern] [COUNT count] summary: Incrementally iterate hash fields and associated values since: 2.8.0 HSET key field value summary: Set the string value of a hash field since: 2.0.0 HSETNX key field value summary: Set the value of a hash field, only if the field does not exist since: 2.0.0 HSTRLEN key field summary: Get the length of the value of a hash field since: 3.2.0 HVALS key summary: Get all the values in a hash since: 2.0.0127.0.0.1:6379>
命令演示
1. HSET(赋值)和HGET(取值)
127.0.0.1:6379> hset car:1 price 20W(integer) 1127.0.0.1:6379> hget car:1 price"20W"
HSET命令的方便之处在于不区分插入和更新操作,这意味着修改数据时不用事先判断字段是否存在来决定要执行的是插入操作(insert)还是更新操作(update)。当执行的是插入操作 时HSET命令会返回1,当执行的是更新操作时HSET命令会返回0。更进一步,当键本身不存在时,HSET命令还会自动建立它。
2. HMSET(赋值多个)和HMGET(取值多个)
127.0.0.1:6379> hmset car:2 price 20W name BMW(integer) 1127.0.0.1:6379> hmget car:2 price name1)"20W"2)"BMW"
3. HGETALL(获取键中所有字段和字段值)
如果想获取键中所有字段和字段值却不知道键中有哪些字段时可以使用HGETALL命令:
127.0.0.1:6379> hgetall car:21)"20W"2)"BMW"
4. HEXISTS(判断字段是否在)
HEXISTS命令用来判断一个字段是否存在。如果存在则返回1,否则返回0(如果键不存在也会返回0):
127.0.0.1:6379> hexists car:2 model(integer) 0127.0.0.1:6379> hset car:2 model C200(integer) 1127.0.0.1:6379> hexists car:2 model(integer) 1
5. HSETNX(当字段不存在时赋值)
127.0.0.1:6379> FLUSHALLOK127.0.0.1:6379> hset car:2 model c200(integer) 1127.0.0.1:6379> hexists car:2 model(integer) 1127.0.0.1:6379> hsetnx car:2 model c300(integer) 0127.0.0.1:6379> hget car:2 model"c200"
6. HINCRBY(增加数字)
散列类型没有HINCR命令,但是可以通过HINCRBY key field来实现。如下:
127.0.0.1:6379> hincrby duan score 60(integer) 60
之前的duan键不存在,HINCRBY命令会自动建立该键并默认score字段在执行命令前的值为0,命令的返回值是增加后的字段值。
7. HDEL(删除字段)
HDEL命令可以删除一个或多个字段,返回值是被删除的字段个数:
127.0.0.1:6379> hdel car:2 price(integer) 1127.0.0.1:6379> hdel car:2 price(integer) 0
8. HKEYS(只获取字段名)和HVALS(只获取字段值)
127.0.0.1:6379> hkeys car:21)"name"2)"model"127.0.0.1:6379> hvals car:21)"BMW"2)"C200"
9. HLEN(获取字段数量)
127.0.0.1:6379> hlen car:2(integer) 2
四、hash类型总结
hash与string对比,相似的api:
redis过期针对key设置的,对字符串key设置过期时间,而无法对hash的属性设置过期时间
hash当不断增加key时导致不断扩容,所以最好对hash类型的key进行分片存储,避免hash类型频繁扩容
哈希操作时间复杂度总结:
命令 | 复杂度 |
hget hset hdel | o(1) |
hexists | o(1) |
hincrby | o(1) |
hgetall hvals hkeys | o(n) |
hmget hmset | o(n) |
推荐阅读
Redis开篇介绍
Redis值类型之string
Redis值类型之list
看完本文有收获?请转发分享给更多人
关注「并发编程之美」,一起交流Java学习心得