java高效重复数据删除

时间:2010-02-25 05:32:06

标签: java large-data-volumes

假设您有一个大文本文件。每行包含一个电子邮件ID和一些其他信息(比如一些product-id)。假设文件中有数百万行。您必须在数据库中加载此数据。您如何有效地删除重复数据(即消除重复数据)?

6 个答案:

答案 0 :(得分:8)

疯狂的行数

  • 使用Map& Reduce框架(例如Hadoop)。这是一个完整的分布式计算,所以除非你有TB的数据,否则这是一个过度杀手。 (j / k :))

无法容纳内存中的所有行

  • 即使结果也不合适:使用合并排序,将中间数据保存到磁盘。合并时,您可以丢弃重复项(可能this sample帮助)。如果您愿意,这可以是多线程的。
  • 结果将适合:您可以使用行迭代器或其他东西,而不是读取内存中的所有内容然后将其放入HashSet(见下文),并继续添加到此HashSet。您可以使用ConcurrentHashMap并使用多个线程来读取文件并添加到此Map。另一个多线程选项是使用ConcurrentSkipListSet。在这种情况下,您将实现compareTo()而不是equals()/ hashCode()(compareTo()== 0表示重复)并继续添加到此SortedSet。

适合内存

  • 设计一个保存数据的对象,实现一个好的equals()/ hashCode()方法并将它们全部放在HashSet中。
  • 或者使用上面给出的方法(你可能不想坚持使用磁盘)。

哦,如果我是你,我会在数据库中加上唯一约束......

答案 1 :(得分:1)

我将从明显的答案开始。创建一个hashmap并将电子邮件ID作为键,将其余信息放入值中(或使对象保存所有信息)。当你到达一个新行时,检查密钥是否存在,是否确实移动到下一行。最后使用HashMap写出所有SQL语句。我同意eqbridges,如果你有一个“gazillion”行,内存限制将是重要的。

答案 2 :(得分:1)

您有两种选择,

  1. 在Java中执行:您可以将类似HashSet的内容放在一起进行测试 - 如果集合中不存在,则为每个项目添加电子邮件ID。

  2. 在数据库中执行:在表上放置一个唯一约束,这样就不会在表中添加重复项。另外一个好处是,您可以重复此过程并删除之前运行中的重复项。

答案 3 :(得分:1)

看看杜克(https://github.com/larsga/Duke)一个用java编写的快速重复数据删除和记录链接引擎。它使用Lucene来索引并减少比较次数(以避免不可接受的笛卡尔积比较)。它支持最常见的算法(编辑距离,jaro winkler等),并且它具有极高的可扩展性和可配置性。

答案 4 :(得分:0)

您是否可以通过电子邮件和产品ID索引表格?然后按索引阅读应该通过顺序读取轻松识别电子邮件或电子邮件+ prodId的副本,并简单地匹配以前的记录。

答案 5 :(得分:0)

您的问题可以通过Extract, transform, load (ETL)方法解决:

  • 您在导入架构中加载数据;
  • 对数据进行每次转换;
  • 然后将其加载到目标数据库架构中。

您可以手动执行此操作或使用ETL工具。