redis五种基本数据结构
本文会介绍Redis的五种数据结构以及他们的使用场景,并附有Demo
string
redis的字符串是动态字符串,可以修改。int(数字的时候)、raw(长字符串,长度大于39字节)、embstr(短字符串,长度小于39字符串)。支持二进制安全、自动拓展、减小内存分配次数
字符串长度不能超过512M
底层实现:
SDS(Simple Dynamic String)
使用场景:
计数、普通存储、锁
typescript
@Service
public class RedisStringService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
public void incrementValue(String key) {
// 使用 RedisTemplate 执行 INCR 命令
Long incrementedValue = redisTemplate.opsForValue().increment(key, 1);
System.out.println("Incremented value of " + key + ": " + incrementedValue);
}
// 获取值的示例
public String getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
}
hash
redis的hash相当于Java的HashMap,内部结构实现与HashMap一致,即数组+链表结构。redis的hash的值只能是字符串。ziplist(所有字符串元素长度都小于64字节、元素小于512)、哈希表(不满足ziplist的条件)
底层实现:
zipList
hashtable
使用场景:
- 存储用户信息、商品信息(等对象类型信息)
typescript
@Service
public class RedisHashService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
// 新增或修改 Hash 字段
public void setHashField(String hashKey, String field, String value) {
// 使用 opsForHash() 来操作 Hash 数据
redisTemplate.opsForHash().put(hashKey, field, value);
}
// 获取 Hash 中的字段值
public String getHashField(String hashKey, String field) {
return (String) redisTemplate.opsForHash().get(hashKey, field);
}
// 获取整个 Hash
public Map<Object, Object> getAllHashFields(String hashKey) {
return redisTemplate.opsForHash().entries(hashKey);
}
}
list
底层实现:
ziplist(所有字符串元素长度都小于64字节、元素小于512)
双向链表linkedlist(不满足ziplist的其他情况)
使用场景:消息队列(生产者LPUSH、消费者RPOP)、任务调度、日志存储(这两个本质上也是消息队列)、分页展示(getRange方法)、最新评论等
typescript
@Service
public class RedisListService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
// 向 List 左侧添加元素
public void pushLeft(String listKey, String value) {
redisTemplate.opsForList().leftPush(listKey, value);
}
// 向 List 右侧添加元素
public void pushRight(String listKey, String value) {
redisTemplate.opsForList().rightPush(listKey, value);
}
// 从 List 左侧弹出元素
public String popLeft(String listKey) {
return (String) redisTemplate.opsForList().leftPop(listKey);
}
// 从 List 右侧弹出元素
public String popRight(String listKey) {
return (String) redisTemplate.opsForList().rightPop(listKey);
}
// 获取列表的长度
public Long getListLength(String listKey) {
return redisTemplate.opsForList().size(listKey);
}
// 获取列表指定范围的元素
public List<String> getRange(String listKey, long start, long end) {
return redisTemplate.opsForList().range(listKey, start, end);
}
}
set
无需的集合数据类型,每个元素唯一,inset(所有元素都是整数、长度小于512)、哈希表(不满足inset条件)
底层实现:
intset(整数集合,适用于小证书集合,元素紧凑形式存储)
hashtable
使用场景:
去重、标签管理、最近访问用户、热门关键词、集合计算(互相好友等)
typescript
@Service
public class RedisSetService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
// 向 Set 中添加元素
public void addToSet(String setKey, String value) {
redisTemplate.opsForSet().add(setKey, value);
}
// 从 Set 中删除元素
public void removeFromSet(String setKey, String value) {
redisTemplate.opsForSet().remove(setKey, value);
}
// 获取 Set 中所有元素
public Set<String> getAllFromSet(String setKey) {
return redisTemplate.opsForSet().members(setKey);
}
// 获取 Set 中的元素数量
public Long getSetSize(String setKey) {
return redisTemplate.opsForSet().size(setKey);
}
// 检查元素是否在 Set 中
public Boolean isMemberOfSet(String setKey, String value) {
return redisTemplate.opsForSet().isMember(setKey, value);
}
// 从 Set 中随机移除一个元素
public String popFromSet(String setKey) {
return (String) redisTemplate.opsForSet().pop(setKey);
}
// 获取 Set 的交集
public Set<String> getSetIntersection(String setKey1, String setKey2) {
return redisTemplate.opsForSet().intersect(setKey1, setKey2);
}
// 获取 Set 的并集
public Set<String> getSetUnion(String setKey1, String setKey2) {
return redisTemplate.opsForSet().union(setKey1, setKey2);
}
// 获取 Set 的差集
public Set<String> getSetDifference(String setKey1, String setKey2) {
return redisTemplate.opsForSet().difference(setKey1, setKey2);
}
}
zset
(有序集合)
底层实现:
ziplist(所有字符串元素长度都小于64字节、元素小于512)
跳表与hashtable组合(不满足ziplist的其他情况)
hashtable存储value和score的映射,skiplist按照从小到大的分数顺序存储分数
使用场景:
排行榜、优先队列
typescript
@Service
public class RedisZSetService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
// 向 ZSet 中添加元素
public void addToZSet(String zSetKey, String value, double score) {
redisTemplate.opsForZSet().add(zSetKey, value, score);
}
// 获取 ZSet 中指定范围的元素(按分数排序)
public Set<String> getRangeByScore(String zSetKey, double minScore, double maxScore) {
return redisTemplate.opsForZSet().rangeByScore(zSetKey, minScore, maxScore);
}
// 获取 ZSet 中指定排名区间的元素(按排名排序) -- 分数高的在开头
public Set<String> getRangeByRank(String zSetKey, long start, long end) {
return redisTemplate.opsForZSet().range(zSetKey, start, end);
}
// 获取 ZSet 中指定元素的分数
public Double getScore(String zSetKey, String value) {
return redisTemplate.opsForZSet().score(zSetKey, value);
}
// 获取 ZSet 中元素的数量
public Long getZSetSize(String zSetKey) {
return redisTemplate.opsForZSet().size(zSetKey);
}
// 从 ZSet 中移除指定元素
public void removeFromZSet(String zSetKey, String value) {
redisTemplate.opsForZSet().remove(zSetKey, value);
}
// 获取 ZSet 中的排名(按分数排序,最小排名为0)
public Long getRank(String zSetKey, String value) {
return redisTemplate.opsForZSet().rank(zSetKey, value);
}
// 获取 ZSet 中指定分数区间的所有元素,按分数降序排序。
public Set<String> getRangeByScoreDesc(String zSetKey, double minScore, double maxScore) {
return redisTemplate.opsForZSet().reverseRangeByScore(zSetKey, minScore, maxScore);
}
// 获取 ZSet 中的元素按排名降序排列
public Set<String> getRangeByRankDesc(String zSetKey, long start, long end) {
return redisTemplate.opsForZSet().reverseRange(zSetKey, start, end);
}
}