Redis 数据类型及应用场景——Hash
今天来接着聊下redis数据类型中的哈希(hash) 数据类型,说到hash可能大家都不是很陌生,hash是一种数据的存储方式,它是根据不同的键名通过某种算法计算出一个地址值,那这个地址值就是存储相应键值的地址,当然有的时候会出现多个不同的键算出来的地址是一样的,那这个时候就需要用到冲突解决方法(redis使用拉链法),这里就不深入去研究这块的东西,今天主要来看下Redis hash 的一些操作及其应用场景。
1. Hash简介
我们知道Redis是采用字典的结构以键值对的形式存储数据,而散列类型(hash)的键值也是一种字典结构,存储了字段和字段值的映射,但是字段值只能是字符串,其实就是说hash不能嵌套其他的数据类型,比如集合类型。一个散列类型键最多可以包含2^32-1个字段,哈希对象的底层实现可以是ziplist或者hashtable。
2. 实际应用中遇到的一些问题
比如我们的博客网站,假设之前我们将所有的文章信息以序列化方式保存在redis里面,比如键post:文章ID,文章的标题,内容等字段序列化后保存在其中。现在有了一个新的需求就是我们要做一个文章列表,这个文章列表只显示标题部分,那这个时候不得不把整个文章数据字符串取出来后反序列化一下,而其中占用空间最大的文章内容是不需要的,这样就会在数据传输和处理时造成资源浪费,另外,比如我们想更新某篇文章,我们先要读取出来,解析后再更改,这个时候如果有两个客户端同时操作的话就会造成数据错乱。所以,为了解决这个问题我们采用hash。
3. 实践
上面提到如果我们把文章数据序列化后存储到一个键中,可是这种方法没办法提供对单个字段的原子读写操作的,从而会导产生竞态条件。这个时候我们用hash来替代,下图展示了hash存储结构。

接下来我们看下关于hash有哪些操作
hset post:42 title '这是第一篇文章';
hset post:42 author '小明';
hset post:42 publish_time '2019-09-09' ;
hset post:42 content '今天是个好日子';
hgetall post:42 ;//获取所有的字段和字段值
hget post:42 title; // 这是第一篇文章,获取title
hget post:42 author;//小明
hdel post:42 author; //删除author属性
hlen post:42;// 3,返回字段的个数
//批量设置和获取(一个key里面多个字段)
hmset post:43 title '这是第二篇文章' author '小明' pusblish_time '2019-09-10' content '今天是个好日子';
hmget post:43 title author publish_time content;
hexists post:43 author;// 判断字段author是否存在
hkeys post:43;//获取所有的键值
hvals post:43;// 获取所有的value
//数值
hset post:43 views 43; //设置文章的查看数
hincrby post:43 views 1;// views + 1
hincrbyfloat post:43 views 2;// 浮点型加2
总结:
看了上面这么多操作,我们得出hash 特别适合存储对象,可以直接更新对象中的某个字段值而不需要把数据从redis里面取出来处理后再设置回去,大大提高了效率。