Redis如何实现数据的交集、并集和补集

71次阅读
没有评论

共计 5072 个字符,预计需要花费 13 分钟才能阅读完成。

本篇内容介绍了“Redis 如何实现数据的交集、并集和补集”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

场景说明

今天我们来模拟一个这样的场景,我们在本地有多个文本文件,每个文件里面存了很多的 32 位的字符串作为用户的唯一标识,每个用户存做一行,假如我们每天都有非常大规模的用户,这样我们可能在工作中就存在需要对这些用户进行交集、并集或补集等处理,最简单的方式是通过 Java 中的集合来进行运算即可,比如通过 HashSet 来进行相应的一些运算,但是这样的运算存在一个局限性,那就是我们一般在 JVM 运行过程中初始的内存是有限的,这样如果全部在 JVM 内存中进行计算的话,很容易出现内存空间不足导致的 OOM 异常,那么我们今天来介绍一种拓展性更强的方式来进行这样的一些交并补的运算:通过 Redis 来实现数据的交集、并集、补集

环境说明

Redis 版本:Redis 6.0.6

Jedis 版本:4.2.2

工具类 hutool 版本:5.8.0.M3

pom 文件:

dependencies 
  dependency 
  groupId redis.clients /groupId 
  artifactId jedis /artifactId 
  version 4.2.2 /version 
  /dependency 
  dependency 
  groupId cn.hutool /groupId 
  artifactId hutool-all /artifactId 
  version 5.8.0.M3 /version 
  /dependency /dependencies

交并补计算初始化常量

public class RedisCalculateUtils {
 static String oneFileString =  /Users/tmp/test-1.txt 
 static String twoFileString =  /Users/tmp/test-2.txt 
 static String diffFileString =  /Users/tmp/diff-test.txt 
 static String interFileString =  /Users/tmp/inter-test.txt 
 static String unionFileString =  /Users/tmp/union-test.txt 
 static String oneFileCacheKey =  oneFile 
 static String twoFileCacheKey =  twoFile 
 static String diffFileCacheKey =  diffFile 
 static String interFileCacheKey =  interFile 
 static String unionFileCacheKey =  unionFile 
 }

初始化数据到指定文件

/**
*  初始化数据并写入文件中
*/public static void writeFile() { File oneFile = new File(oneFileString);
 List String  fs = new ArrayList (10000);
 for (int i = 10000; i   15000; i++) { String s = SecureUtil.md5(String.valueOf(i));
 fs.add(s);
 }
 FileUtil.writeUtf8Lines(fs, oneFile);
 File twoFile = new File(twoFileString);
 fs.clear();
 for (int i = 12000; i   20000; i++) { String s = SecureUtil.md5(String.valueOf(i));
 fs.add(s);
 }
 FileUtil.writeUtf8Lines(fs, twoFile);
 }

指定文件写入 Redis

/**
*  读取文件数据并写入 Redis
*/public static void writeCache() { try(Jedis jedis = new Jedis( 127.0.0.1 , 6379)) { Pipeline p = jedis.pipelined();
 List String  oneFileStringList = FileUtil.readLines(oneFileString,  UTF-8 
 for (String s : oneFileStringList) { p.sadd(oneFileCacheKey, s);
 }
 p.sync();
 List String  twoFileStringList = FileUtil.readLines(twoFileString,  UTF-8 
 for (String s : twoFileStringList) { p.sadd(twoFileCacheKey, s);
 }
 p.sync();
 } catch (Exception e) { throw new RuntimeException(e);
 }}

差集的计算

 /**
 * oneKey 对应的 Set  与  twoKey 对应的 Set  的差集   并写入  threeKey
 * @param oneKey  差集前面的集合 Key
 * @param twoKey  差集后面的集合 Key
 * @param threeKey  差集结果的集合 Key
 */
 public static void diff(String oneKey, String twoKey, String threeKey) { try(Jedis jedis = new Jedis( 127.0.0.1 , 6379)) { long result = jedis.sdiffstore(threeKey, oneKey, twoKey);
 System.out.println(oneKey  与  twoKey  的差集的个数: + result);
 } catch (Exception e) { throw new RuntimeException(e);
 }
 }

差集计算结果写入到指定文件

 /**
 *  将计算的差集数据写入到指定文件
 */
 public static void writeDiffToFile() { File diffFile = new File(diffFileString);
 try(Jedis jedis = new Jedis( 127.0.0.1 , 6379)) { Set String  result = jedis.smembers(diffFileCacheKey);
 FileUtil.writeUtf8Lines(result, diffFile);
 } catch (Exception e) { throw new RuntimeException(e);
 }
 }

交集的计算

/**
 *
 * @param cacheKeyArray  交集集合 Key
 * @param destinationKey  交集集合结果 Key
 */
 public static void inter(String[] cacheKeyArray, String destinationKey) { try(Jedis jedis = new Jedis( 127.0.0.1 , 6379)) { long result = jedis.sinterstore(destinationKey, cacheKeyArray);
 System.out.println(cacheKeyArray  的交集的个数: + result);
 } catch (Exception e) { throw new RuntimeException(e);
 }
 }

交集计算结果写入指定文件

 /**
 *  将计算的交集数据写入到指定文件
 */
 public static void writeInterToFile() { File interFile = new File(interFileString);
 try(Jedis jedis = new Jedis( 127.0.0.1 , 6379)) { Set String  result = jedis.smembers(interFileCacheKey);
 FileUtil.writeUtf8Lines(result, interFile);
 } catch (Exception e) { throw new RuntimeException(e);
 }
 }

并集的计算

 /**
 *  计算多个 Key 的并集并写入到新的 Key
 * @param cacheKeyArray  求并集的 Key
 * @param destinationKey  并集结果写入的 KEY
 */
 public static void union(String[] cacheKeyArray, String destinationKey) { try(Jedis jedis = new Jedis( 127.0.0.1 , 6379)) { long result = jedis.sunionstore(destinationKey, cacheKeyArray);
 System.out.println(cacheKeyArray  的并集的个数: + result);
 } catch (Exception e) { throw new RuntimeException(e);
 }
 }

并集计算结果写入到指定文件

 /**
 *  将计算的并集数据写入到指定文件
 */
 public static void writeUnionToFile() { File unionFile = new File(unionFileString);
 try(Jedis jedis = new Jedis( 127.0.0.1 , 6379)) { Set String  result = jedis.smembers(unionFileCacheKey);
 FileUtil.writeUtf8Lines(result, unionFile);
 } catch (Exception e) { throw new RuntimeException(e);
 }
 }

Redis 命令说明 SDIFFSTORE destination key [key …]

举例说明:

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SDIFF key1 key2 key3 = {b,d}

SDIFFSTORE 命令的作用和 SDIFF 类似,不同的是它将结果保存到 destination 集合,而把结果集返回给客户端。

如果 destination 集合已经存在,则将其覆盖。

返回值
结果集中成员数量

SINTERSTORE destination key [key …]

举例说明:

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SINTER key1 key2 key3 = {c}

SINTERSTORE 命令与 SINTER 命令类似,不同的是它并不是直接返回结果集,而是将结果保存在 destination 集合中。

如果 destination 集合存在, 则会被覆盖。

返回值
结果集中成员数量

SUNIONSTORE destination key [key …]

举例说明:

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SUNION key1 key2 key3 = {a,b,c,d,e}

SUNIONSTORE 命令的功能类似于 SUNION,不同的是不反回结果集,而是存储在 destination 中。

如果 destination 已经存在,则被覆盖。

返回值
结果集中的成员数量

“Redis 如何实现数据的交集、并集和补集”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-13发表,共计5072字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)