3_hash(字典)
2023/7/3...大约 3 分钟
Redis基础类型——hash(字典)
介绍基本概念
Redis的字典相当于Java语言里的HashMap,它是无序字典,内部存储了很多键值对。实现结构上与Java的HashMap也是一样的,都是“数组+链表”的二维结构,第一维hash的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。
与Java不同地方是,Redis的字典值只能是字符串,他们的rehash方式不一样。
Java的HashMap在字典很大时,rehash是一个耗时的操作,需要一次性全部rehash
Redis为了追求高性能,不能堵塞服务,所以采用了渐进式rehash策略。
渐进式rehash会在rehash的同时,保留新旧两个hash结构,查询时会同时查两个hash结构,然后再后续的定时任务以及hash操作指令中,循序渐进地将旧hash的内容一点点迁移到新hash结构中。搬迁完成,就会使用新的hash结构取代旧的hash。
当hash移除最后一个元素之后,该数据结构被自动删除,内存被回收。
使用:
 hash结构可以存储用户信息,与字符串需要一次性全部序列化整个对象不同,hash可以对用户结构中的每个字段单独存储。
 hash结构中单个key也可进行计数,使用hincrby
优点:
获取是可以进行部分获取。相比于以整个字符串形式去保存用户信息(一次只能全部读取),节省网络流量
hash缺点:
hash结构存储消耗要高于单个字符串
命令与Java方法对应关系
Java方法基于redisTemplate.opsForList()。
| 命令 | Java方法 | 描述 | 
|---|---|---|
| HSET | put(object, key, value) | 将哈希表 key 中的域 field 的值设为 value | 
| HGET | get(object, key) | 返回哈希表 key 中给定域 field 的值。 | 
| HKEYS | keys(object) | 返回哈希表 key 中的所有域。 | 
| HVALS | values(object) | 返回哈希表 key 中所有域的值 | 
| HGETALL | entries(object) | 返回哈希表 key 中,所有的域和值 | 
| HEXISTS | hasKey(object, key) | 查看哈希表 key 中,给定域 field 是否存在 | 
  HashOperations hashOperations = redisTemplate.opsForHash();
  // 将哈希表 key 中的域 field 的值设为 value 。
  //如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。
  //如果域 field 已经存在于哈希表中,旧值将被覆盖。
  String object = "Object", hashKey1 = "hashKey1", hashKey2 = "hashKey2", hashValue1 = "hashValue1", hashValue2 = "hashValue2";
  hashOperations.put(object, hashKey1, hashValue1);
  hashOperations.put(object, hashKey2, hashValue2);
  // 返回哈希表 key 中给定域 field 的值。
  Object result = hashOperations.get(object, hashKey1);
  // 返回哈希表 key 中的所有域。
  Set set = hashOperations.keys(object);
  //返回哈希表 key 中所有域的值
  List list = hashOperations.values(object);
  // 返回哈希表 key 中,所有的域和值。
  //在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
  Map map = hashOperations.entries(object);
  // 查看哈希表 key 中,给定域 field 是否存在
  hashOperations.hasKey(object, hashKey1);问题
如果用hash结构来缓存用户信息,该如何封装比较合适?