Redis十大数据类型应用场景及代码示例

一 字符串(String)

Redis 的字符串类型(String)是 Redis 中最基本的数据类型,它的使用非常广泛,几乎所有的应用场景都可以涉及到字符串的操作。下面,我们将通过一个虚拟电商平台的示例来展示 Redis 字符串类型的各种操作和应用场景。

应用场景

假设我们正在开发一个电商平台,需要管理以下几个方面:

  1. 商品库存管理:跟踪商品的库存数量。

  2. 用户积分管理:管理用户的积分余额。

  3. 用户登录状态:跟踪用户的登录状态(如活跃用户)。

  4. 缓存查询结果:缓存一些频繁查询的数据,如商品详情。

Java 代码示例

1. 商品库存管理

设置和获取库存数量

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 设置商品库存
public void setProductStock(String productId, int stock) {
    redisTemplate.opsForValue().set("product:stock:" + productId, String.valueOf(stock));
}
​
// 获取商品库存
public int getProductStock(String productId) {
    String stock = redisTemplate.opsForValue().get("product:stock:" + productId);
    return stock == null ? 0 : Integer.parseInt(stock);
}
​
// 扣减库存
public void decrementProductStock(String productId, int quantity) {
    redisTemplate.opsForValue().decrement("product:stock:" + productId, quantity);
}

示例

// 设置商品 ID 为 100 的库存为 50
setProductStock("100", 50);
​
// 获取商品 ID 为 100 的库存
int stock = getProductStock("100"); // 50
​
// 扣减库存 5 个
decrementProductStock("100", 5); // 剩余库存 45
2. 用户积分管理

设置和获取用户积分

// 设置用户积分
public void setUserPoints(String userId, int points) {
    redisTemplate.opsForValue().set("user:points:" + userId, String.valueOf(points));
}
​
// 获取用户积分
public int getUserPoints(String userId) {
    String points = redisTemplate.opsForValue().get("user:points:" + userId);
    return points == null ? 0 : Integer.parseInt(points);
}
​
// 增加用户积分
public void addUserPoints(String userId, int points) {
    redisTemplate.opsForValue().increment("user:points:" + userId, points);
}

示例

// 设置用户 ID 为 1 的积分为 100
setUserPoints("1", 100);
​
// 获取用户 ID 为 1 的积分
int points = getUserPoints("1"); // 100
​
// 增加用户 ID 为 1 的积分 50
addUserPoints("1", 50); // 总积分 150
3. 用户登录状态

设置和检查用户登录状态

// 设置用户登录状态
public void setUserLoggedIn(String userId) {
    redisTemplate.opsForValue().set("user:login:" + userId, "true");
}
​
// 检查用户是否在线
public boolean isUserLoggedIn(String userId) {
    String status = redisTemplate.opsForValue().get("user:login:" + userId);
    return "true".equals(status);
}
​
// 用户登出
public void setUserLoggedOut(String userId) {
    redisTemplate.opsForValue().set("user:login:" + userId, "false");
}

示例

// 用户 ID 为 1 登录
setUserLoggedIn("1");
​
// 检查用户 ID 为 1 是否在线
boolean isLoggedIn = isUserLoggedIn("1"); // true
​
// 用户 ID 为 1 登出
setUserLoggedOut("1");
4. 缓存查询结果

缓存商品详情

// 设置商品详情缓存
public void cacheProductDetails(String productId, String details) {
    redisTemplate.opsForValue().set("product:details:" + productId, details);
}
​
// 获取商品详情缓存
public String getCachedProductDetails(String productId) {
    return redisTemplate.opsForValue().get("product:details:" + productId);
}

示例

// 缓存商品 ID 为 100 的详情
cacheProductDetails("100", "{\"name\": \"Laptop\", \"price\": 1200}");
​
// 获取商品 ID 为 100 的缓存详情
String details = getCachedProductDetails("100"); // "{\"name\": \"Laptop\", \"price\": 1200}"

Redis 命令示例

  • 设置商品库存

    SET product:stock:100 50
  • 获取商品库存

    GET product:stock:100
  • 扣减库存

    DECRBY product:stock:100 5
  • 设置用户积分

    SET user:points:1 100
  • 获取用户积分

    GET user:points:1
  • 增加用户积分

    INCRBY user:points:1 50
  • 设置用户登录状态

    SET user:login:1 true
  • 检查用户登录状态

    GET user:login:1
  • 用户登出

    SET user:login:1 false
  • 缓存商品详情

    SET product:details:100 "{\"name\": \"Laptop\", \"price\": 1200}"
  • 获取缓存商品详情

    GET product:details:100

这些代码示例和 Redis 命令展示了 Redis 字符串类型的各种操作和应用场景,帮助你在实际应用中灵活使用 Redis 的字符串类型。

二 哈希(Hash)

Redis 哈希是一种键值对的集合,用于存储对象类型的数据。下面,我们将通过一个虚拟电商平台的示例来展示 Redis 哈希类型(Hash)的各种操作和应用场景。哈希类型特别适用于存储和操作与对象相关的数据。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 用户信息管理:存储和更新用户的个人信息。

  2. 商品信息管理:存储和更新商品的详细信息。

  3. 订单信息管理:存储和查询订单的详细信息。

Java 代码示例

1. 用户信息管理

设置和获取用户信息

@Autowired
private RedisTemplate<String, Object> redisTemplate;
​
// 设置用户信息
public void setUserInfo(String userId, Map<String, String> userInfo) {
    redisTemplate.opsForHash().putAll("user:" + userId, userInfo);
}
​
// 获取用户信息
public Map<Object, Object> getUserInfo(String userId) {
    return redisTemplate.opsForHash().entries("user:" + userId);
}
​
// 更新用户邮箱
public void updateUserEmail(String userId, String email) {
    redisTemplate.opsForHash().put("user:" + userId, "email", email);
}
​
// 获取用户的特定字段
public String getUserField(String userId, String field) {
    return (String) redisTemplate.opsForHash().get("user:" + userId, field);
}

示例

// 设置用户 ID 为 1 的信息
Map<String, String> userInfo = new HashMap<>();
userInfo.put("username", "JohnDoe");
userInfo.put("email", "john@example.com");
userInfo.put("registered", "2024-08-04");
setUserInfo("1", userInfo);
​
// 获取用户 ID 为 1 的信息
Map<Object, Object> userInfoMap = getUserInfo("1"); // 包含 "username", "email", "registered"
​
// 更新用户 ID 为 1 的邮箱
updateUserEmail("1", "new_email@example.com");
​
// 获取用户 ID 为 1 的邮箱
String email = getUserField("1", "email"); // "new_email@example.com"
2. 商品信息管理

设置和获取商品信息

// 设置商品信息
public void setProductInfo(String productId, Map<String, String> productInfo) {
    redisTemplate.opsForHash().putAll("product:" + productId, productInfo);
}
​
// 获取商品信息
public Map<Object, Object> getProductInfo(String productId) {
    return redisTemplate.opsForHash().entries("product:" + productId);
}
​
// 更新商品价格
public void updateProductPrice(String productId, String price) {
    redisTemplate.opsForHash().put("product:" + productId, "price", price);
}
​
// 获取商品的特定字段
public String getProductField(String productId, String field) {
    return (String) redisTemplate.opsForHash().get("product:" + productId, field);
}

示例

// 设置商品 ID 为 100 的信息
Map<String, String> productInfo = new HashMap<>();
productInfo.put("name", "Laptop");
productInfo.put("price", "1200");
productInfo.put("stock", "50");
setProductInfo("100", productInfo);
​
// 获取商品 ID 为 100 的信息
Map<Object, Object> productInfoMap = getProductInfo("100"); // 包含 "name", "price", "stock"
​
// 更新商品 ID 为 100 的价格
updateProductPrice("100", "1150");
​
// 获取商品 ID 为 100 的价格
String price = getProductField("100", "price"); // "1150"
3. 订单信息管理

设置和获取订单信息

// 设置订单信息
public void setOrderInfo(String orderId, Map<String, String> orderInfo) {
    redisTemplate.opsForHash().putAll("order:" + orderId, orderInfo);
}
​
// 获取订单信息
public Map<Object, Object> getOrderInfo(String orderId) {
    return redisTemplate.opsForHash().entries("order:" + orderId);
}
​
// 更新订单状态
public void updateOrderStatus(String orderId, String status) {
    redisTemplate.opsForHash().put("order:" + orderId, "status", status);
}
​
// 获取订单的特定字段
public String getOrderField(String orderId, String field) {
    return (String) redisTemplate.opsForHash().get("order:" + orderId, field);
}

示例

// 设置订单 ID 为 500 的信息
Map<String, String> orderInfo = new HashMap<>();
orderInfo.put("userId", "1");
orderInfo.put("productId", "100");
orderInfo.put("quantity", "1");
orderInfo.put("status", "pending");
setOrderInfo("500", orderInfo);
​
// 获取订单 ID 为 500 的信息
Map<Object, Object> orderInfoMap = getOrderInfo("500"); // 包含 "userId", "productId", "quantity", "status"
​
// 更新订单 ID 为 500 的状态
updateOrderStatus("500", "shipped");
​
// 获取订单 ID 为 500 的状态
String status = getOrderField("500", "status"); // "shipped"

Redis 命令示例

  • 用户信息管理

    HSET user:1 username "JohnDoe"
    HSET user:1 email "john@example.com"
    HSET user:1 registered "2024-08-04"
    ​
    HGETALL user:1
    ​
    HSET user:1 email "new_email@example.com"
    ​
    HGET user:1 email
  • 商品信息管理

    HSET product:100 name "Laptop"
    HSET product:100 price "1200"
    HSET product:100 stock "50"
    ​
    HGETALL product:100
    ​
    HSET product:100 price "1150"
    ​
    HGET product:100 price
  • 订单信息管理

    HSET order:500 userId "1"
    HSET order:500 productId "100"
    HSET order:500 quantity "1"
    HSET order:500 status "pending"
    ​
    HGETALL order:500
    ​
    HSET order:500 status "shipped"
    ​
    HGET order:500 status

这些代码示例和 Redis 命令展示了 Redis 哈希类型的各种操作和应用场景。哈希类型非常适合存储和管理具有多个字段的数据对象,并允许对字段进行高效的操作。

三 列表(List)

Redis 列表是一个按插入顺序排序的字符串列表,支持从两端推送和弹出元素。下面,我们将通过一个虚拟电商平台的示例来展示 Redis 列表类型(List)的各种操作和应用场景。Redis 列表类型适合于需要有序存储和操作数据的场景。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 用户购物车:管理用户的购物车,包括添加、查看和删除购物车中的商品。

  2. 订单历史记录:存储用户的订单历史,以便用户查看历史订单。

  3. 最近浏览的商品:记录用户最近浏览过的商品,用于推荐相关商品。

Java 代码示例

1. 用户购物车

添加、查看和删除购物车中的商品

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 添加商品到购物车
public void addToCart(String userId, String product) {
    redisTemplate.opsForList().leftPush("cart:" + userId, product);
}
​
// 获取购物车中的商品列表
public List<String> getCartItems(String userId) {
    return redisTemplate.opsForList().range("cart:" + userId, 0, -1);
}
​
// 移除购物车中的商品
public void removeFromCart(String userId, String product) {
    redisTemplate.opsForList().remove("cart:" + userId, 1, product);
}

示例

// 添加商品到用户 ID 为 1 的购物车
addToCart("1", "product:100");
addToCart("1", "product:200");
​
// 获取用户 ID 为 1 的购物车商品
List<String> cartItems = getCartItems("1"); // ["product:200", "product:100"]
​
// 移除购物车中的商品
removeFromCart("1", "product:100");
2. 订单历史记录

添加和获取订单历史记录

// 添加订单到用户历史记录
public void addOrderToHistory(String userId, String orderId) {
    redisTemplate.opsForList().leftPush("orderHistory:" + userId, orderId);
}
​
// 获取用户的订单历史
public List<String> getOrderHistory(String userId) {
    return redisTemplate.opsForList().range("orderHistory:" + userId, 0, -1);
}

示例

// 添加订单到用户 ID 为 1 的历史记录
addOrderToHistory("1", "order:500");
addOrderToHistory("1", "order:501");
​
// 获取用户 ID 为 1 的订单历史
List<String> orderHistory = getOrderHistory("1"); // ["order:501", "order:500"]
3. 最近浏览的商品

记录和获取最近浏览的商品

// 添加商品到最近浏览列表
public void addRecentlyViewed(String userId, String productId) {
    redisTemplate.opsForList().leftPush("recentlyViewed:" + userId, productId);
}
​
// 获取用户最近浏览的商品
public List<String> getRecentlyViewed(String userId) {
    return redisTemplate.opsForList().range("recentlyViewed:" + userId, 0, -1);
}

示例

// 添加商品到用户 ID 为 1 的最近浏览列表
addRecentlyViewed("1", "product:300");
addRecentlyViewed("1", "product:400");
​
// 获取用户 ID 为 1 的最近浏览商品
List<String> recentlyViewed = getRecentlyViewed("1"); // ["product:400", "product:300"]

Redis 命令示例

  • 用户购物车

    LPUSH cart:1 "product:100"
    LPUSH cart:1 "product:200"
    ​
    LRANGE cart:1 0 -1
    ​
    LREM cart:1 1 "product:100"
  • 订单历史记录

    LPUSH orderHistory:1 "order:500"
    LPUSH orderHistory:1 "order:501"
    ​
    LRANGE orderHistory:1 0 -1
  • 最近浏览的商品

    LPUSH recentlyViewed:1 "product:300"
    LPUSH recentlyViewed:1 "product:400"
    ​
    LRANGE recentlyViewed:1 0 -1

这些代码示例和 Redis 命令展示了 Redis 列表类型的各种操作和应用场景。Redis 列表类型适用于需要有序操作的数据,如购物车、历史记录和最近浏览的商品等。

四 集合(Set)

Redis 的集合类型(Set)是一种无序的集合,它不允许重复的元素。集合类型非常适合处理需要去重、集合运算(如交集、并集、差集)的数据。下面我们将通过一个虚拟电商平台的示例来展示 Redis 集合类型的各种操作和应用场景。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 用户收藏的商品:管理用户收藏的商品列表,并进行去重操作。

  2. 商品的标签:为商品分配标签,支持标签的集合运算(如查找拥有多个标签的商品)。

  3. 系统黑名单:管理系统中的黑名单用户,以便进行禁止操作。

Java 代码示例

1. 用户收藏的商品

添加、获取和删除用户收藏的商品

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 添加商品到用户收藏
public void addFavorite(String userId, String productId) {
    redisTemplate.opsForSet().add("favorites:" + userId, productId);
}
​
// 获取用户收藏的商品列表
public Set<String> getFavorites(String userId) {
    return redisTemplate.opsForSet().members("favorites:" + userId);
}
​
// 删除用户收藏的商品
public void removeFavorite(String userId, String productId) {
    redisTemplate.opsForSet().remove("favorites:" + userId, productId);
}

示例

// 添加商品到用户 ID 为 1 的收藏列表
addFavorite("1", "product:100");
addFavorite("1", "product:200");
​
// 获取用户 ID 为 1 的收藏列表
Set<String> favorites = getFavorites("1"); // ["product:100", "product:200"]
​
// 删除用户 ID 为 1 的收藏商品
removeFavorite("1", "product:100");
2. 商品的标签

为商品添加和获取标签

// 为商品添加标签
public void addTagToProduct(String productId, String tag) {
    redisTemplate.opsForSet().add("product:tags:" + productId, tag);
}
​
// 获取商品的所有标签
public Set<String> getProductTags(String productId) {
    return redisTemplate.opsForSet().members("product:tags:" + productId);
}
​
// 查找拥有特定标签的商品
public Set<String> getProductsByTag(String tag) {
    return redisTemplate.opsForSet().members("tag:" + tag);
}
​
// 将商品和标签关联
public void associateProductWithTag(String productId, String tag) {
    redisTemplate.opsForSet().add("tag:" + tag, productId);
}

示例

// 为商品 ID 为 100 添加标签
addTagToProduct("100", "electronics");
addTagToProduct("100", "laptop");
​
// 获取商品 ID 为 100 的所有标签
Set<String> tags = getProductTags("100"); // ["electronics", "laptop"]
​
// 将标签和商品关联
associateProductWithTag("100", "electronics");
​
// 获取所有标记为 "electronics" 的商品
Set<String> products = redisTemplate.opsForSet().members("tag:electronics"); // ["100"]
3. 系统黑名单

添加、获取和删除黑名单用户

// 添加用户到黑名单
public void addToBlacklist(String userId) {
    redisTemplate.opsForSet().add("blacklist", userId);
}
​
// 获取黑名单中的所有用户
public Set<String> getBlacklist() {
    return redisTemplate.opsForSet().members("blacklist");
}
​
// 移除用户从黑名单
public void removeFromBlacklist(String userId) {
    redisTemplate.opsForSet().remove("blacklist", userId);
}

示例

// 添加用户 ID 为 1 的到黑名单
addToBlacklist("1");
​
// 获取黑名单中的所有用户
Set<String> blacklist = getBlacklist(); // ["1"]
​
// 移除用户 ID 为 1 从黑名单
removeFromBlacklist("1");

Redis 命令示例

  • 用户收藏的商品

    SADD favorites:1 "product:100"
    SADD favorites:1 "product:200"
    ​
    SMEMBERS favorites:1
    ​
    SREM favorites:1 "product:100"
  • 商品的标签

    SADD product:tags:100 "electronics"
    SADD product:tags:100 "laptop"
    ​
    SMEMBERS product:tags:100
    ​
    SADD tag:electronics "100"
    ​
    SMEMBERS tag:electronics
  • 系统黑名单

    SADD blacklist "1"
    ​
    SMEMBERS blacklist
    ​
    SREM blacklist "1"

这些代码示例和 Redis 命令展示了 Redis 集合类型的各种操作和应用场景。集合类型非常适合处理无序的、去重的数据,并支持高效的集合运算,如并集、交集和差集。

五 有序集合(Sorted Set)

Redis 的有序集合类型(Sorted Set)是 Redis 中的一个非常强大的数据结构。它结合了集合的唯一性和列表的排序特性。每个元素在有序集合中都有一个分数(score),并且集合中的元素会根据分数自动排序。这使得有序集合非常适合用于处理需要按分数排序的数据,例如排行榜、优先队列等。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 用户积分排行榜:展示用户积分的排行榜。

  2. 商品评分系统:根据用户评分对商品进行排序。

  3. 任务优先级管理:按照任务的优先级处理任务。

Java 代码示例

1. 用户积分排行榜

添加用户积分、获取排行榜和获取用户排名

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 添加用户积分
public void addUserScore(String userId, double score) {
    redisTemplate.opsForZSet().add("user:scoreboard", userId, score);
}
​
// 获取用户积分排行榜
public Set<ZSetOperations.TypedTuple<String>> getScoreboard(int start, int end) {
    return redisTemplate.opsForZSet().rangeWithScores("user:scoreboard", start, end);
}
​
// 获取用户排名
public Long getUserRank(String userId) {
    return redisTemplate.opsForZSet().reverseRank("user:scoreboard", userId);
}

示例

// 添加用户 ID 为 1 和 2 的积分
addUserScore("1", 1000.0);
addUserScore("2", 1500.0);
​
// 获取用户积分排行榜,前 10 名
Set<ZSetOperations.TypedTuple<String>> scoreboard = getScoreboard(0, 9);
​
// 获取用户 ID 为 1 的排名
Long rank = getUserRank("1"); // 排名在列表中的位置
2. 商品评分系统

添加和获取商品评分

// 添加商品评分
public void addProductScore(String productId, double score) {
    redisTemplate.opsForZSet().add("product:ratings", productId, score);
}
​
// 获取商品评分
public Set<ZSetOperations.TypedTuple<String>> getTopRatedProducts(int start, int end) {
    return redisTemplate.opsForZSet().reverseRangeWithScores("product:ratings", start, end);
}

示例

// 为商品 ID 为 100 和 200 添加评分
addProductScore("100", 4.5);
addProductScore("200", 4.8);
​
// 获取评分前 5 的商品
Set<ZSetOperations.TypedTuple<String>> topRatedProducts = getTopRatedProducts(0, 4);
3. 任务优先级管理

添加任务优先级、获取任务列表和移除任务

// 添加任务和优先级
public void addTask(String taskId, double priority) {
    redisTemplate.opsForZSet().add("task:priority", taskId, priority);
}
​
// 获取优先级最高的任务
public Set<ZSetOperations.TypedTuple<String>> getHighestPriorityTasks(int start, int end) {
    return redisTemplate.opsForZSet().reverseRangeWithScores("task:priority", start, end);
}
​
// 移除任务
public void removeTask(String taskId) {
    redisTemplate.opsForZSet().remove("task:priority", taskId);
}

示例

// 添加任务 ID 为 1 和 2 的优先级
addTask("1", 5.0);
addTask("2", 3.0);
​
// 获取优先级最高的前 10 个任务
Set<ZSetOperations.TypedTuple<String>> highestPriorityTasks = getHighestPriorityTasks(0, 9);
​
// 移除任务 ID 为 1
removeTask("1");

Redis 命令示例

  • 用户积分排行榜

    ZADD user:scoreboard 1000 "1"
    ZADD user:scoreboard 1500 "2"
    ​
    ZREVRANGE user:scoreboard 0 9 WITHSCORES
    ​
    ZREVRANK user:scoreboard "1"
  • 商品评分系统

    ZADD product:ratings 4.5 "100"
    ZADD product:ratings 4.8 "200"
    ​
    ZREVRANGE product:ratings 0 4 WITHSCORES
  • 任务优先级管理

    ZADD task:priority 5.0 "1"
    ZADD task:priority 3.0 "2"
    ​
    ZREVRANGE task:priority 0 9 WITHSCORES
    ​
    ZREM task:priority "1"

这些代码示例和 Redis 命令展示了 Redis 有序集合类型的各种操作和应用场景。有序集合非常适合用于需要排序和排名的数据处理,例如排行榜、评分系统和优先级队列等。

六 位图(Bitmap)

Redis 的 Bitmap 类型是一个用于高效存储和操作二进制位的数据结构。它在需要大规模位运算的场景中非常有用,比如统计用户活跃度、跟踪事件发生情况等。Bitmap 可以被视为一个字符串,但每个字符的位置代表一个位(bit),允许你进行位级操作。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 用户登录状态:记录用户每日的登录状态(已登录或未登录)。

  2. 活动参与情况:跟踪用户是否参与了某个活动。

  3. 广告点击统计:统计广告的点击情况。

Java 代码示例

1. 用户登录状态

设置和获取用户的登录状态

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 设置用户登录状态
public void setUserLoginStatus(String userId, int dayOfMonth, boolean status) {
    redisTemplate.opsForValue().setBit("user:login:" + userId, dayOfMonth, status);
}
​
// 获取用户登录状态
public boolean getUserLoginStatus(String userId, int dayOfMonth) {
    return redisTemplate.opsForValue().getBit("user:login:" + userId, dayOfMonth);
}

示例

// 设置用户 ID 为 1 在 4 号登录状态为 true
setUserLoginStatus("1", 4, true);
​
// 获取用户 ID 为 1 在 4 号的登录状态
boolean loginStatus = getUserLoginStatus("1", 4); // true
2. 活动参与情况

记录用户参与活动

// 记录用户参与活动
public void recordUserParticipation(String activityId, String userId) {
    redisTemplate.opsForValue().setBit("activity:" + activityId, userId.hashCode(), true);
}
​
// 检查用户是否参与了活动
public boolean hasUserParticipated(String activityId, String userId) {
    return redisTemplate.opsForValue().getBit("activity:" + activityId, userId.hashCode());
}

示例

// 记录用户 ID 为 1 参与了活动 ID 为 101
recordUserParticipation("101", "1");
​
// 检查用户 ID 为 1 是否参与了活动 ID 为 101
boolean participated = hasUserParticipated("101", "1"); // true
3. 广告点击统计

记录和获取广告点击情况

// 记录广告点击
public void recordAdClick(String adId, int clickIndex) {
    redisTemplate.opsForValue().setBit("ad:clicks:" + adId, clickIndex, true);
}
​
// 获取广告点击总数
public long getAdClickCount(String adId) {
    return redisTemplate.execute((RedisCallback<Long>) connection -> connection.bitCount("ad:clicks:" + adId.getBytes()));
}

示例

// 记录广告 ID 为 200 的第 5 次点击
recordAdClick("200", 5);
​
// 获取广告 ID 为 200 的点击总数
long clickCount = getAdClickCount("200"); // 返回点击的位数总和

Redis 命令示例

  • 用户登录状态

    SETBIT user:login:1 4 1
    ​
    GETBIT user:login:1 4
  • 活动参与情况

    SETBIT activity:101 1 1
    ​
    GETBIT activity:101 1
  • 广告点击统计

    SETBIT ad:clicks:200 5 1
    ​
    BITCOUNT ad:clicks:200

这些代码示例和 Redis 命令展示了 Redis Bitmap 类型的各种操作和应用场景。Bitmap 在处理大规模位操作时非常高效,适用于需要进行位级统计和标记的场景。

七 HyperLogLog

Redis 的 HyperLogLog 是一个用于估算集合中不同元素数量的数据结构。它特别适合于处理需要高效存储和估算大规模数据集合的场景,如统计独立用户数量或独立事件数量。HyperLogLog 可以在使用较少内存的情况下提供接近准确的结果。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 独立访问用户统计:估算网站的独立访问用户数量。

  2. 独立商品浏览统计:统计浏览过不同商品的独立用户数量。

  3. 唯一广告点击统计:估算广告被点击的独立用户数量。

Java 代码示例

1. 独立访问用户统计

添加用户访问记录和获取用户总数

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 记录用户访问
public void recordUserVisit(String visitId, String userId) {
    redisTemplate.opsForHyperLogLog().add(visitId, userId);
}
​
// 获取估算的独立用户数量
public Long getUniqueUserCount(String visitId) {
    return redisTemplate.opsForHyperLogLog().size(visitId);
}

示例

// 记录用户 ID 为 1 和 2 访问网站
recordUserVisit("site:visits", "1");
recordUserVisit("site:visits", "2");
​
// 获取估算的独立用户数量
Long uniqueUserCount = getUniqueUserCount("site:visits"); // 2
2. 独立商品浏览统计

记录用户浏览商品和获取浏览过的独立商品数量

// 记录用户浏览商品
public void recordProductView(String productId, String userId) {
    redisTemplate.opsForHyperLogLog().add("product:" + productId + ":views", userId);
}
​
// 获取浏览过商品的独立用户数量
public Long getUniqueProductViewers(String productId) {
    return redisTemplate.opsForHyperLogLog().size("product:" + productId + ":views");
}

示例

// 记录用户 ID 为 1 和 2 浏览了商品 ID 为 100
recordProductView("100", "1");
recordProductView("100", "2");
​
// 获取浏览商品 ID 为 100 的独立用户数量
Long uniqueViewers = getUniqueProductViewers("100"); // 2
3. 唯一广告点击统计

记录广告点击和获取点击的独立用户数量

// 记录广告点击
public void recordAdClick(String adId, String userId) {
    redisTemplate.opsForHyperLogLog().add("ad:" + adId + ":clicks", userId);
}
​
// 获取点击广告的独立用户数量
public Long getUniqueAdClickers(String adId) {
    return redisTemplate.opsForHyperLogLog().size("ad:" + adId + ":clicks");
}

示例

// 记录用户 ID 为 1 和 2 点击了广告 ID 为 200
recordAdClick("200", "1");
recordAdClick("200", "2");
​
// 获取点击广告 ID 为 200 的独立用户数量
Long uniqueClickers = getUniqueAdClickers("200"); // 2

Redis 命令示例

  • 独立访问用户统计

    PFADD site:visits "1" "2"
    ​
    PFCOUNT site:visits
  • 独立商品浏览统计

    PFADD product:100:views "1" "2"
    ​
    PFCOUNT product:100:views
  • 唯一广告点击统计

    PFADD ad:200:clicks "1" "2"
    ​
    PFCOUNT ad:200:clicks

这些代码示例和 Redis 命令展示了 Redis HyperLogLog 类型的各种操作和应用场景。HyperLogLog 在处理需要高效估算独立元素数量的场景中非常有用,如网站访问统计、商品浏览统计和广告点击统计等。

八 地理空间 (Geospatial)

Redis 的地理空间数据结构(Geospatial)用于存储和查询地理位置数据。Redis 支持地理位置的存储、距离计算和附近位置的查询等功能,这对于实现位置服务和地理相关应用非常有用。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 商店位置查询:查找离用户最近的商店。

  2. 配送服务:找到离配送地点最近的仓库。

  3. 活动推荐:根据用户当前位置推荐附近的活动。

Java 代码示例

1. 商店位置查询

添加商店位置和查询最近的商店

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 添加商店位置
public void addStoreLocation(String storeId, double latitude, double longitude) {
    redisTemplate.opsForGeo().add("stores", new Point(longitude, latitude), storeId);
}
​
// 查找离用户最近的商店
public List<GeoLocation<String>> getNearbyStores(double userLat, double userLon, double radius) {
    Circle within = new Circle(new Point(userLon, userLat), radius);
    return redisTemplate.opsForGeo().radius("stores", within, GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending());
}

示例

// 添加商店位置
addStoreLocation("store1", 37.7749, -122.4194); // San Francisco
addStoreLocation("store2", 34.0522, -118.2437); // Los Angeles
​
// 查找离用户位置(37.7749, -122.4194)5公里内的商店
List<GeoLocation<String>> nearbyStores = getNearbyStores(37.7749, -122.4194, 5000); // 半径为5公里
2. 配送服务

添加仓库位置和查询最近的仓库

// 添加仓库位置
public void addWarehouseLocation(String warehouseId, double latitude, double longitude) {
    redisTemplate.opsForGeo().add("warehouses", new Point(longitude, latitude), warehouseId);
}
​
// 查找离配送地点最近的仓库
public List<GeoLocation<String>> getNearbyWarehouses(double deliveryLat, double deliveryLon, double radius) {
    Circle within = new Circle(new Point(deliveryLon, deliveryLat), radius);
    return redisTemplate.opsForGeo().radius("warehouses", within, GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending());
}

示例

// 添加仓库位置
addWarehouseLocation("warehouse1", 40.7128, -74.0060); // New York
addWarehouseLocation("warehouse2", 41.8781, -87.6298); // Chicago
​
// 查找离配送地点(40.7128, -74.0060)100公里内的仓库
List<GeoLocation<String>> nearbyWarehouses = getNearbyWarehouses(40.7128, -74.0060, 100000); // 半径为100公里
3. 活动推荐

添加活动位置和查询附近的活动

// 添加活动位置
public void addEventLocation(String eventId, double latitude, double longitude) {
    redisTemplate.opsForGeo().add("events", new Point(longitude, latitude), eventId);
}
​
// 查找离用户位置最近的活动
public List<GeoLocation<String>> getNearbyEvents(double userLat, double userLon, double radius) {
    Circle within = new Circle(new Point(userLon, userLat), radius);
    return redisTemplate.opsForGeo().radius("events", within, GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending());
}

示例

// 添加活动位置
addEventLocation("event1", 37.7749, -122.4194); // San Francisco
addEventLocation("event2", 34.0522, -118.2437); // Los Angeles
​
// 查找离用户位置(37.7749, -122.4194)50公里内的活动
List<GeoLocation<String>> nearbyEvents = getNearbyEvents(37.7749, -122.4194, 50000); // 半径为50公里

Redis 命令示例

  • 商店位置查询

    GEOADD stores -122.4194 37.7749 "store1"
    GEOADD stores -118.2437 34.0522 "store2"
    ​
    GEORADIUS stores -122.4194 37.7749 5000 km WITHDIST ASC
  • 配送服务

    GEOADD warehouses -74.0060 40.7128 "warehouse1"
    GEOADD warehouses -87.6298 41.8781 "warehouse2"
    ​
    GEORADIUS warehouses -74.0060 40.7128 100 km WITHDIST ASC
  • 活动推荐

    GEOADD events -122.4194 37.7749 "event1"
    GEOADD events -118.2437 34.0522 "event2"
    ​
    GEORADIUS events -122.4194 37.7749 50000 km WITHDIST ASC

这些代码示例和 Redis 命令展示了 Redis 地理空间数据结构的各种操作和应用场景。地理空间数据结构非常适合用于处理位置相关的数据,如查找附近的商店、仓库或活动等。

九 流(Stream)

Redis Streams 是 Redis 5.0 引入的一种数据结构,用于处理实时数据流和消息队列。它提供了高效的数据流存储、消费和处理能力,适用于日志记录、事件处理、实时分析等场景。

应用场景

假设我们在开发一个电商平台,需要管理以下几个方面:

  1. 订单日志:记录用户的订单操作。

  2. 实时消息队列:处理实时的用户活动数据。

  3. 事件流处理:跟踪和处理实时事件,如用户登录、商品浏览等。

Java 代码示例

1. 订单日志

添加订单记录和获取订单记录

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 添加订单记录
public void addOrder(String orderId, Map<String, String> orderDetails) {
    redisTemplate.opsForStream().add("orders", orderDetails);
}
​
// 获取订单记录
public List<MapRecord<String, String, String>> getOrders(long count) {
    return redisTemplate.opsForStream().read(Consumer.from("group", "consumer"), StreamReadOptions.empty().count(count), "orders");
}

示例

// 添加订单记录
Map<String, String> orderDetails = new HashMap<>();
orderDetails.put("userId", "1");
orderDetails.put("productId", "100");
orderDetails.put("quantity", "2");
​
addOrder("order:123", orderDetails);
​
// 获取最新的 10 个订单记录
List<MapRecord<String, String, String>> orders = getOrders(10);
2. 实时消息队列

添加消息和获取消息

// 添加消息
public void addMessage(String channel, Map<String, String> message) {
    redisTemplate.opsForStream().add(channel, message);
}
​
// 获取消息
public List<MapRecord<String, String, String>> getMessages(String channel, long count) {
    return redisTemplate.opsForStream().read(Consumer.from("group", "consumer"), StreamReadOptions.empty().count(count), channel);
}

示例

// 添加消息
Map<String, String> message = new HashMap<>();
message.put("event", "user_signup");
message.put("userId", "1");
​
addMessage("user:events", message);
​
// 获取最新的 10 条消息
List<MapRecord<String, String, String>> messages = getMessages("user:events", 10);
3. 事件流处理

添加事件和获取事件

// 添加事件
public void addEvent(String eventType, Map<String, String> eventData) {
    redisTemplate.opsForStream().add("events:" + eventType, eventData);
}
​
// 获取事件
public List<MapRecord<String, String, String>> getEvents(String eventType, long count) {
    return redisTemplate.opsForStream().read(Consumer.from("group", "consumer"), StreamReadOptions.empty().count(count), "events:" + eventType);
}

示例

// 添加事件
Map<String, String> eventData = new HashMap<>();
eventData.put("action", "login");
eventData.put("userId", "1");
​
addEvent("login", eventData);
​
// 获取最新的 10 个登录事件
List<MapRecord<String, String, String>> events = getEvents("login", 10);

Redis 命令示例

  • 订单日志

    XADD orders * userId 1 productId 100 quantity 2
    ​
    XRANGE orders - + COUNT 10
  • 实时消息队列

    XADD user:events * event user_signup userId 1
    ​
    XRANGE user:events - + COUNT 10
  • 事件流处理

    XADD events:login * action login userId 1
    ​
    XRANGE events:login - + COUNT 10

这些代码示例和 Redis 命令展示了 Redis Streams 类型的各种操作和应用场景。Redis Streams 提供了强大的流数据处理能力,适合用于处理日志记录、消息队列和事件流等实时数据处理任务。

十 BitField

Redis 的 BitField 类型用于处理比特位操作,可以用来存储和操作大量的位数据。BitField 类型支持高效的位运算操作,适用于处理位数组、位掩码以及其他需要按位操作的场景。

应用场景

假设我们在开发一个游戏统计系统,需要管理以下几个方面:

  1. 玩家成就记录:记录玩家完成的成就或任务。

  2. 用户权限控制:管理用户的权限位。

  3. 事件标记:标记事件是否发生过。

Java 代码示例

1. 玩家成就记录

设置玩家成就和获取成就状态

@Autowired
private RedisTemplate<String, String> redisTemplate;
​
// 设置玩家成就
public void setAchievement(String playerId, int bitOffset) {
    redisTemplate.opsForValue().setBit("player:" + playerId + ":achievements", bitOffset, true);
}
​
// 获取玩家成就状态
public Boolean getAchievement(String playerId, int bitOffset) {
    return redisTemplate.opsForValue().getBit("player:" + playerId + ":achievements", bitOffset);
}

示例

// 设置玩家 ID 为 1 的成就,成就位偏移量为 5
setAchievement("1", 5);
​
// 获取玩家 ID 为 1 的成就状态,偏移量为 5
Boolean achievement = getAchievement("1", 5); // true or false
2. 用户权限控制

设置用户权限位和获取权限状态

// 设置用户权限
public void setUserPermission(String userId, int bitOffset) {
    redisTemplate.opsForValue().setBit("user:" + userId + ":permissions", bitOffset, true);
}
​
// 获取用户权限状态
public Boolean getUserPermission(String userId, int bitOffset) {
    return redisTemplate.opsForValue().getBit("user:" + userId + ":permissions", bitOffset);
}

示例

// 设置用户 ID 为 1 的权限位偏移量为 3
setUserPermission("1", 3);
​
// 获取用户 ID 为 1 的权限状态,偏移量为 3
Boolean permission = getUserPermission("1", 3); // true or false
3. 事件标记

设置事件标记和获取事件状态

// 设置事件标记
public void setEventFlag(String eventId, int bitOffset) {
    redisTemplate.opsForValue().setBit("event:" + eventId + ":flags", bitOffset, true);
}
​
// 获取事件标记状态
public Boolean getEventFlag(String eventId, int bitOffset) {
    return redisTemplate.opsForValue().getBit("event:" + eventId + ":flags", bitOffset);
}

示例

// 设置事件 ID 为 "event1" 的标记位偏移量为 2
setEventFlag("event1", 2);
​
// 获取事件 ID 为 "event1" 的标记状态,偏移量为 2
Boolean eventFlag = getEventFlag("event1", 2); // true or false

Redis 命令示例

  • 玩家成就记录

    SETBIT player:1:achievements 5 1
    GETBIT player:1:achievements 5
  • 用户权限控制

    SETBIT user:1:permissions 3 1
    GETBIT user:1:permissions 3
  • 事件标记

    SETBIT event:event1:flags 2 1
    GETBIT event:event1:flags 2

BitField 扩展操作

设置和获取多位数据

// 批量设置和获取位数据,使用 BitField 操作
// 设置 8 位宽的整数值,起始偏移量为 0
redisTemplate.execute((RedisCallback<Long>) connection -> 
    connection.bitField("bitfield:key".getBytes(), BitFieldSubCommands.create().set(BitFieldSubCommands.BitFieldType.unsigned(8).at(0), 123)
));
​
// 获取 8 位宽的整数值
redisTemplate.execute((RedisCallback<Long>) connection -> 
    connection.bitField("bitfield:key".getBytes(), BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(8).at(0))
));

Redis 命令示例

BITFIELD bitfield:key SET u8 0 123
BITFIELD bitfield:key GET u8 0

这些代码示例和 Redis 命令展示了 Redis BitField 类型的各种操作和应用场景。BitField 适合于需要处理大量位数据的场景,如记录成就、权限管理和事件标记等。

  • 37
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愤怒的代码

如果您有受益,欢迎打赏博主😊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值