Redis数据结构--哈希hash
如果内存足够大 ,那么一个 Redis 的 hash 结构可以存储2的32次方-1个键值对 ( 40多亿)。
在 Redis 中, hash 是一个 String 类型的 field 和 value 的映射表,因此存储的数据实际在 Redis 内存中都是一个字符串。
假设User有三个字段: id name sex
在 Redis 中它就是一个这样的结构,其中 user代表的是 hash 结构在 Redis 内存的 key,通过就可以找到这个 hash 结构,而 hash 结构由一系列的 field 和 value 组成

hash 结构命令

在 Redis 中的哈希结构和字符串的不同:
首先,命令都是以 h 开头,代表操作的是 hash 结构
其次,大多数命令多一个层级 field,这是hash 结构的一个内部键,也就是说Redis 需要通过 key 索引到对应的 hash 结构,再通过 field来确定使用 hash 结构的哪个键值对
注意事项:
哈希结构的大小,如果哈希结构是个很大的键值对,那么使用它要十分注意。 尤其是关于 hkeys 、 hgetall 、 hvals 等返回所有哈希结构数据的命令,会造成大量数据的读取。这需要考虑性能和读取数据大小对 JVM 内存的影响 。
对于数字的操作命令 hincrby 而言,要求存储的也是整数型的字符串
对于hincrbyfloat 而言,则要求使用浮点数或者整数,否则命令会失败。
Spring操作hash
package com.smart; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import java.util.*; public class RedisStringDemo { public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:redis/spring-redis.xml"); // redisTemplate.opsForValue()所返回的对象可以操作简单的键值对,可以是字符串,也可以是对象,具体依据所配置的序列化方案 // 在spring-redis-string.xml中key和value是指定的 stringRedisSerializer RedisTemplate redisTemplate= (RedisTemplate<String, String>) context.getBean("redisTemplate"); flushDb(redisTemplate); String key="role"; Map<String, String> map = new HashMap<String, String>(); map.put("id","11"); map.put("name","jim"); map.put("age",String.valueOf("18")); redisTemplate.opsForHash().putAll(key,map); redisTemplate.opsForHash().put(key,"sex","male"); Boolean isExist = redisTemplate.opsForHash().hasKey(key, "name"); System.out.println(key+"是否存在name这个属性:"+isExist); Map<String,String> entries = redisTemplate.opsForHash().entries(key); if(entries !=null){ printMap(entries); } redisTemplate.opsForHash().put(key, "k4", "6"); System.out.println(redisTemplate.opsForHash().increment(key,"id",3)); System.out.println(redisTemplate.opsForHash().increment(key,"k4",3.4)); Set<String> set = redisTemplate.opsForHash().keys(key); for(String str: set){ System.out.println(str); } List<String> list = new ArrayList<>(); list.add("id"); list.add("name"); list.add("age"); List<String> multiGet = redisTemplate.opsForHash().multiGet(key, list); printList(multiGet); System.out.println(redisTemplate.opsForHash().size(key)); System.out.println(redisTemplate.opsForHash().putIfAbsent(key,"id","test")); System.out.println(redisTemplate.opsForHash().putIfAbsent(key,"sex","text")); } public static void printMap(Map<String,String> map){ for(Map.Entry<String,String> entry : map.entrySet()){ System.out.println("key= "+entry.getKey()+", value="+entry.getValue()); } } public static void printList(List<String> list){ for(String s: list){ System.out.println(s); } } public static String flushDb(RedisTemplate<String,String> redisTemplate){ return redisTemplate.execute(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection connection) throws DataAccessException { connection.flushDb(); return "ok"; } }); } }
在 Spring 中使用 redisTemplate.opsForHash().putAll(key, map )方法相当于执行了hmset 命令,使用了 map ,由于配置了默认的序列化器为字符串,所以它也只会用字符串进行转化,这样才能执行对应的数值加法,如果使用其他序列化器,则后面的命令可能会抛出异常。
在使用大的 hash 结构时,需要考虑返回数据的大小,以避免返回太多的数据,引发JVM内存溢出或者 Redis 的性能问题。
参考:
原文:https://artisan.blog.csdn.net/article/details/82788441
浙公网安备 33010602011771号