如何在临时本地存储中存储数百万个条目

时间:2018-01-17 18:19:20

标签: java database hashmap runtime

我正在从一个数据库到另一个数据库进行数百万条数据的迁移工作。在第一个数据库中,我有两个不同的表(我可以将其作为我下载的文本文件访问 - 我无权访问数据库) (1)城市 - 其中每一行都是一个城市对象,实例变量由制表符分隔(例如id name population

(2)CitiesToTopics - 其中每一行是城市id和相应的主题(例如id topic)。这不是每行唯一的。因此,2行可以共享一个id,这意味着相应的城市有2个主题[topic1,topic2]。

在这次迁移中,我将创建一个名为City的新POJO

public class City {
    private long id;
    private String name;
    private long population;
    private List<String> topics;
    // removed getters and setters
}

将这些城市添加到我的新数据库中。

我想首先查询CitiesToTopics表并创建一个

HashMap<String, List<String>> citiesToTopics映射每个ID - &gt;列表[专题]。

然后,查询第二个表,并为每一行获取id并执行 List<String> topics = citiesToTopics.get(id)然后创建City(id, name, population, topics)

除了在CitiesToTopics中有超过2600万个城市和大约1.5亿个条目之外,这一切都很好。因此,当我尝试运行程序时,我不断收到内存错误或GC错误。我已升级到fastutil hashmap,但我收到了“Java运行时环境已检测到致命错误”。我不能真正使用外部数据库来容纳我的临时citiesToTopics,因为SQLite可以做大约950次插入/秒,在我的情况下意味着需要大约2天才能运行。有没有更好的方法来处理这么多数据,特别是当它真的只是一种确保每个城市都能获得适当主题的临时方式时?

提前致谢,

编辑:必要的按摩 - 这就是我需要创建临时数据结构的原因 - 是将一行id topic作为字符串,将行分为{{ 1}}并将其放入地图中。然后,取一条\t的行,按id name population分割,创建一个新的\t,它将是{“Id”:“97987987”,“name”:“Boston”,“人口“:”673,184“,”主题“:[”夏天“,”冬天“]}。

2 个答案:

答案 0 :(得分:3)

你能做的是:

  • 按ID对两个文件进行排序。例如,在linux上,您可以使用类似cat file | sort -k1 > sorted_file(未经测试)的内容,这可能会在合理的时间内完成这一操作(在较大的文件上需要几个小时,但不是几天)
  • 以同步的方式对城市和主题文件进行一次迭代,现在您知道所有记录都已排序,并在N个城市的批量中填充新数据库。您不会需要比批量大小更多的内存。

答案 1 :(得分:1)

@assylias是对的:按ID排序城市文件,然后按城市ID排序citiesToTopics。重点是对这些文件进行排序。在这种情况下,您不需要在处理之前将整个文件拉入内存或其他任何地方,并且您的程序将使用非常少的内存,新结构中只有一个对象,并且每个文件只有一行。

例如,您的程序可以有两个嵌套循环(伪代码):

nextCityToTopic = CityToTopicsFile.readFirstLine
for each city in citiesFile {
       city = citiesFile.readNextLine
       newJsonStructure = createNewforCity
       curCityId = city.id
       do {              
         if nextCityToTopic.cityId == nextCityToTopic.cityId {
              add Topic into newJsonStructure 
              nextCityToTopic = CityToTopicsFile.readNextLine
         } else {
            insert newJsonStructure into database
            break
         }             
       } while CityToTopicsFile.hasMoreLines
}

P.S。实际上它是对@assylias帖子的评论。对不起它非常大 - 所以我只是添加了一个答案。