redis系列(三)—数据结构之哈希(hash)

在这里插入图片描述

前言

大家好,牧码心今天给大家推荐一篇redis系列—数据结构之哈希(hash)的文章,在实际工作中有很多应用场景,希望对你有所帮助。内容如下:

  • 特点
  • 基本命令
  • 时间复杂度
  • 使用场景

特点

在Redis中, 哈希类型是指键值本身又是一个键值对结构, 形如value={{field1, value1}, …{fieldN, valueN}}, Redis键值对和哈希类型二者的关系可以用图来表示:
hash结构

基本命令

  • 设置值
hset key field value

下面为user: 1添加一对field-value:

127.0.0.1:6379> hset user:1 name tom
(integer) 1

如果设置成功会返回1, 反之会返回0。

  • 获取值
hget key field

下面操作获取user: 1的name域(属性) 对应的值:

127.0.0.1:6379> hget user:1 name
"tom"

如果键或field不存在, 会返回nil。

  • 删除field
hdel key field [field ...]

hdel会删除一个或多个field, 返回结果为成功删除field的个数, 例如:

127.0.0.1:6379> hdel user:1 name
(integer) 1
  • 批量设置或获取field-value
hmget key field [field ...]
hmset key field value [field value ...]

hmset和hmget分别是批量设置和获取field-value, hmset需要的参数是key
和多对field-value, hmget需要的参数是key和多个field。 例如:

127.0.0.1:6379> hmset user:1 name mike age 12 city tianjin
OK
127.0.0.1:6379> hmget user:1 name city
1) "mike"
2) "tianjin
  • 判断field是否存在
hexists key field

如 user:1包含name域, 所以返回结果为1, 不包含时返回0:

127.0.0.1:6379> hexists user:1 name
(integer) 1
  • 获取所有field
hkeys key
  • 获取所有value
hvals key
  • 获取所有的field-value
hgetall key

下面操作获取user: 1所有的field-value:

127.0.0.1:6379> hgetall user:1
1) "name"
2) "mike"
3) "age"
4) "12"
5) "city"
6) "tianjin"

在使用hgetall时, 如果哈希元素个数比较多, 会存在阻塞Redis的可能。
如果开发人员只需要获取部分field, 可以使用hmget, 如果一定要获取全部
field-value, 可以使用hscan命令, 该命令会渐进式遍历哈希类型。

  • 计算value的字符串长度(需要Redis3.2以上)
hstrlen key field

例如hget user:1 name的value是tom, 那么hstrlen的返回结果是3。

127.0.0.1:6379> hstrlen user:1 name
(integer) 3

时间复杂度

下表哈希类型命令的时间复杂度,开发人员可以参考此表选择适合的命令。
哈希类型命令的时间复杂度

使用场景

假如用关系型数据表记录的两条用户信息, 用户的属性作为表的列,
每条用户信息作为行。如图:
关系型数据库表保存用户信息
用哈希类型类型存储,如图:
哈希类型缓存用户信息
相比于使用字符串序列化缓存用户信息, 哈希类型变得更加直观, 并且在更新操作上会更加便捷。可以将每个用户的id定义为键后缀, 多对fieldvalue对应每个用户的属性, 类似如下伪代码:

UserInfo getUserInfo(long id){
// 用户id作为key后缀
userRedisKey = "user:info:" + id;
// 使用hgetall获取所有用户信息映射关系
userInfoMap = redis.hgetAll(userRedisKey);
UserInfo userInfo;
if (userInfoMap != null) {
// 将映射关系转换为UserInfo
userInfo = transferMapToUserInfo(userInfoMap);
} else {
// 从MySQL中获取用户信息
userInfo = mysql.get(id);
// 将userInfo变为映射关系使用hmset保存到Redis中
redis.hmset(userRedisKey, transferUserInfoToMap(userInfo));
// 添加过期时间
redis.expire(userRedisKey, 3600);
}r
eturn userInfo;
}

总之,使用哈希类型存储,需要注意:
1、哈希类型是稀疏的, 而关系型数据库是完全结构化的, 例如哈希类型
每个键可以有不同的field, 而关系型数据库一旦添加新的列, 所有行都要为
其设置值(即使为NULL)
2、关系型数据库可以做复杂的关系查询, 而Redis去模拟关系型复杂查询
开发困难, 维护成本高。

发布了91 篇原创文章 · 获赞 27 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/xhwwc110/article/details/104820985