如何在Perl中执行类似于SQL的Join操作?

8
我需要通过合并两个不同的文件来处理一些数据。它们都有两列,可以形成一个主键,我可以使用该主键将它们一侧相匹配。这些文件非常庞大(大约5GB,包含2000万行),因此我需要高效的代码。我如何在Perl中实现这个功能?
以下是示例:
如果文件A包含列:
id, name, lastname, dob, school

文件B包含列

address, id, postcode, dob, email

我需要通过匹配两个文件中的iddob来将这两个文件合并,以得到一个输出文件,该文件将具有以下列:

 id, name, lastname, dob, school, address, postcode, email
6个回答

7

我想创建一个新的 mysql/sqlite/任何数据库,并插入行。这应该是大约20行Perl代码。

当然,这需要轻松访问数据库。

你也可以通过有趣的字段对文件进行排序,然后对于文件1中的每一行,在文件2中查找并打印匹配的行。


2
你可以直接从CPAN(DBD :: SQLite)构建SQLite的副本。顺便说一句,在向SQLite插入大量数据时,请使用大型事务。 - tsee

2

以往的做法是使用系统工具按键序列对两个文件进行排序,然后逐行匹配它们。读取两个文件,如果键匹配,则输出数据。如果不匹配,则读取较小键的文件,直到它们匹配为止。如果文件到达末尾,则将键设置为无限高。当两个键都是无限高时,操作完成。


系统实用程序 join,如果其输入已排序,则甚至会为您执行连接。 - reinierpost

0
或者,浏览这篇不错的Techrepublic文章 - 尽管您仍然可能需要5G内存。我想知道使用Unix/Linux CLI sort/join工具会带给您多少效率提升。只是一个想法。

0

我实际上还没有尝试过这个,但更有创意的解决方案可能是:

  1. 读取每个文件一次,并创建一个映射表,将唯一的id+dob组合与它们在文件中的位置对应起来。使用tell()
  2. 在perl中创建映射表
  3. 使用映射表中的位置和sysread()读取实际数据
  4. 将数据写入新文件

0

你也可以使用我三年前编写的CPAN模块Set::Relation来完成这样的任务,它被设计用于在Perl中执行像join这样的SQL操作。为每个文件创建一个Set::Relation对象,然后使用join()方法。但是需要注意的是,该模块实现时会将所有操作数和结果存储在内存中,因此受限于你的RAM。但是你仍然可以查看其源代码以了解join()方法的工作原理,并基于此实现更高效的版本以满足你的需求。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接