我正在重写一个处理大量数据(大约 100 GB)的应用程序,该应用程序被设计为关系模型。
应用非常复杂;它是某种转换工具,用于开放海量(全球)街道地图数据,并将其转换为我们自己的路线规划软件的地图文件。例如,转换器应用程序保存开放街道地图中的节点及其坐标及其所有标签(远不止这些,但这应该作为这个问题的一个例子)。
现在的情况:
因为这个数据非常庞大,所以我把它拆分成几个文件:每个文件都是从一个ID到一个原子值的映射(假设一个节点的标签列表是一个原子值;它不是但数据存储可以照此处理)。因此,对于节点,我有一个保存节点坐标的文件,一个保存节点名称,一个保存节点标签,其中节点由(非连续)ID 标识。
该应用程序曾经被拆分为多个应用程序。每个应用程序处理一个转换步骤。因此,这样的应用程序只需要处理存储在文件中的部分数据。例如,并非所有应用程序都需要节点的标签,但其中很多都需要节点的坐标。这就是我将关系拆分为文件的原因,每个“列”一个文件。
每个处理步骤可以一次将整个文件读入 RAM 中的数据结构。这确保了查找可以非常有效(如果数据结构是哈希映射)。
我目前正在重写转换器。它现在应该是一个单一的应用程序。它现在不应该为每个“列”使用单独的文件。它应该使用一些众所周知的架构以关系方式保存外部数据,例如数据库,但速度要快得多。
=>哪个库可以提供以下功能?
要求:
它需要非常快速地迭代现有数据(同时不修改行集,而是修改当前行中的一些值)。
它需要提供恒定或接近恒定的查找,类似于哈希映射(同时根本不修改整个关系)。
大多数类型的列都是固定大小的,但通常不是。
它需要能够以每行的常数或对数时间将新行附加到关系中。不需要实时更新某种搜索索引。更新(重建)索引可以在整个处理步骤完成后进行。
一些关系是基于键值的,而另一些关系是(连续索引的)数组。它们都应该提供快速查找。
它不应该是一个单独的进程,就像 MySQL 这样的 DBMS。查询的数量将是巨大的(大约 100 亿),并且将完全成为性能的瓶颈。但是,缓存查询将是一种可能的解决方法:迭代整个表可以在单个查询中完成,而写入表(在同一处理步骤中不会从该表读取数据)可以在批处理查询中发生。但仍然:我猜想序列化、进程间传输和反序列化 SQL 查询将成为瓶颈。
锦上添花:易于使用。如果可以以与 C++ 标准和 Qt 容器类类似的方式使用关系,那就太好了。
非要求 (为什么我不需要 DBMS):
从/到相同的关系同步写入和读取。应用程序分为多个处理步骤;每个步骤都有一组它读取的“输入关系”和它写入的“输出关系”。但是,某些步骤需要读取关系的某些列,同时写入同一关系的其他列。
加盟关系。不同关系之间有一些交叉引用,但是,如果查找速度足够快,它们可以在我的应用程序中解决。
持久存储。转换完成后,将不再需要所有数据。
基于键值的关系永远不会被重新键入;基于数组的关系永远不会被重新索引。