Redis哈希 API
哈希键值结构
key仍然是一个字符串,value其实分为两个部分,field代表某个属性,value代表属性的值。在哈希结构中,可以添加一个新的属性和值,也可以修改或者删除某个属性,这与字符串有很大的不同。如果用字符串实现新增属性的话需要将整个value取出来做一个反序列化,然后添加属性后重新序列化存入Redis中。

特点
实际上哈希是一个Mapmap的结构,也就是外层是一个key-value结构,对于value内部而言又是一个map结构。
对于内部的map结构而言,field不能相同,而value可以相同。
哈希相关API
常用命令

常用命令演示

hmget、hmset

hmget、hmset命令演示

hgetall、hvals、hkeys
小心使用 hgetall
命令,它会返回所有的field和value,如果你的hash key存入了很多属性比如一万条,使用该命令执行速度就会非常慢,牢记redis是单线程的。大多数情况下应该都不需要把所有的属性都取出来。

hgetall、hvals、hkeys命令演示

hsetnx、hincrby、hincrbyfloat

简单实战
记录网站每个用户个人主页的访问量
hincrby user:1:info pageview count
定义一个含有用户ID的key,然后在value中我们增加了pageview属性,用它来记录该用户的访问量。这种方式与字符串不同的是,字符串一个key只能存储访问量,如果还需要存储用户的其他属性,需要再单独定义相应的key,而使用哈希则可以存储用户的完整信息。
缓存视频的基本信息(数据源在MySQL中)伪代码
public VideoInfo get(long id){
String redisKey = redisPrefix + id;
//获取全部属性和值
Map< String,String> hashMap = redis.hgetAll(redisKey);
//将map转换为对象
VideoInfo videoInfo = transferMapToVideo(hashMap);
if (videoInfo == null){
videoInfo = mysql.get(id);
if (videoInfo != null){
//批量设置
redis.hmset(redisKey, transferVideoToMap(videoInfo)));
}
}
return videoInfo;
}
如何更新用户属性
方案一
将用户的ID作为key,然后它的value是将所有的属性作为一个整体序列化的结果,比如是一个json串。如果需要获取就将value取出进行反序列化成相应的对象,如果需要重新写入,就将修改后的对象重新序列化写回给redis

方案二
用户ID和每个属性作为一个key,属性值作为value进行存储。这样更新某个属性值就非常方便,而且添加新的属性也不会影响原有的key,缺点是用户的信息不是一个整体,不便于管理。

方案三
就是我们介绍的使用hash的方式,将所有的属性和值作为hash的value进行存储,可以单独更新或者删除某个属性,并且也可以很方便的添加新的属性。

三种方案对比

哈希总结
