【问题标题】:Algorithm to Merge-Join Large files合并加入大文件的算法
【发布时间】:2011-08-11 13:57:00
【问题描述】:

假设我有四个大文件(太大而无法单独放入内存),其中包含我需要处理的信息。我打算从文件#1 中的每一行生成一个应用程序级对象(记录)。文件 2-4 每个都有组成此 Record 对象所需的附加信息。例如,文件结构可能如下:

文件 #1:
密钥、描述

文件 #2:
密钥、元数据、大小

文件 #3:
来源、速率、键

文件 #4:
key、startDate、endDate

每个文件都有一个代表唯一键的列(在一行中的已知位置)。此密钥在文件之间共享,但不能保证任何一个文件中存在的每个密钥都存在于其他文件中,这意味着我们只会处理所有文件中存在的密钥子集。文件的行未排序。您能否设计一种算法来通过处理这些文件来生成应用程序级对象?

【问题讨论】:

    标签: algorithm memory join merge large-files


    【解决方案1】:

    使用键值存储数据库

    数据库是处理大于内存的数据集的最佳工具。将您的文件放入键值存储(CouchDB 或 Cassandra 之类的 NoSQL DB 会很棒)。使用关键查询解决您的问题。

    使用排序和二分查找

    如果您不能使用数据库,请根据键列对文件进行排序(这可以使用GNU sort 轻松完成)。您可以使用密钥在nlogn 时间访问您的文件。遍历最大的文件,并使用对其他文件的调用来处理每条记录。这样你的磁盘读取可能会被缓存。

    【讨论】:

    • 嗯,我希望它不会变成这样。如果文件中的密钥与我在 NoSQL 解决方案中用于存储这些 Record 对象的密钥不同怎么办?假设我使用另一个唯一键 (UUID),并且它们在这些文件中的“键”仅用于重组这些对象?
    • 您可以定义在 NoSQL DB 中使用的密钥字符串。
    • 只使用对您最方便的键字符串,或者在数据库上使用多个索引。另一方面,虽然 NoSQL 确实不错,但在这个特定的应用程序中,我认为与普通 SQL 数据库相比没有任何好处。
    • 在 NoSQL 中键值查询可能更快:stackoverflow.com/questions/1145726/…
    【解决方案2】:

    您可以将所有内容转储到数据库中(实际上,一个简单的 SQL 就可以了),然后删除“不完整”的记录。

    要按文件进行,您可以这样做:

    • 按 id 键对所有文件进行排序
    • 打开所有排序的文件
    • 从每个文件中读取第一条记录
    • 如果您没有 4 条“匹配”记录,则丢弃 id 最低的一条,直到找到为止
    • 合并 4 个“匹配”记录
    • 冲洗并重复

    【讨论】:

      猜你喜欢
      • 2010-09-12
      • 2014-05-07
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 2021-05-04
      • 1970-01-01
      相关资源
      最近更新 更多