【问题标题】:Creating and querying a large database from CSVs从 CSV 创建和查询大型数据库
【发布时间】:2015-03-25 17:12:47
【问题描述】:

我正在尝试将 9 个相互关联的 csv 中的数据合并到一个数据库中。

我遇到的问题是基本 csv 有 500 万条记录,它需要其他 8 个大型 csv 的信息来创建一个完整的记录,但创建此记录需要一分钟多的时间。

这是问题的简化视图。

基础 CSV 表示车辆

Vehicle {
         vehicle_id,
         engine_id,
         maintenance_id
         veh_eng_maintenance_id,
}

其中maintenance_id是维护对象的主键,还有中间查找步骤。

Lookup
{
    lookup_id,
    veh_eng_maintenance_id,
    schedule_id,
}

其中 schedule_id 是来自另一个 csv 的计划对象的主键,而 veh_eng_maintenance_id 来自车辆。

我的目标是在我的 mongo 数据库中创建一个由 Vehicles 组成的集合

Vehicle {
         vehicle_id,
         engine_id,
         maintenance {
                      description,
                      name, 
                      }
          schedules [
                    schedule {
                              name,
                              description, 
                              date,
                             }
                    ]
          }

现在我正在使用 c# 加载 csv,在 mongo 中为它们创建集合,在 c# 中为它们创建类,然后我正在浏览车辆集合(所有 500 万条记录)并查询所有其他集合以创建完整的车辆记录。

但这需要很长时间,而且动态查询单个车辆而不是事先构建完整的车辆集合也需要很长时间。我想知道是否有一种快速的方法来组合极大的集合,或者一种更快的查询方法。

【问题讨论】:

  • 您可以使用 python 或类似的东西为数据库创建一个脚本,并使用完整的详细信息存储车辆记录,而不是创建由 ID 链接的 9 个不同的表。如果您确实希望数据库中存在其他表,您仍然可以构建它们并使用它们来存储唯一的维护数据等,从而更轻松地创建/编辑车辆记录。
  • 问题是数据从 9 个独立的 csvs 开始,这些 csvs 都是相关的,我无法控制这一点,我的目标是使用 c# 将它们整合到一个但不花费一千小时。额外的表不是必需的,我目前只将它们保存到 mongo,所以我不会在本地耗尽内存。
  • 我喜欢 python 做这种事情;您可以使用 DictReader 将每个 csv 作为字典读取,然后使用大循环来制作数据库脚本。由于所有内容都在字典中,因此您可以使用基本 csv 中给出的 ID 来引用维护数据、车辆数据等。我相信你也可以在 C# 中做同样的事情。看看this SO post,也许用字典而不是迈克尔答案中的列表对象
  • 可能有几处可以改进的地方,不看代码,真的很难说。但是,我建议使用 CSV 阅读器/映射器(例如 joshclose.github.io/CsvHelper)。它的重量很轻,可以为您映射对象。之后,您只需要一个最终类并引用对象并创建一个列表。
  • 这基本上正是我现在正在做的问题是它真的很慢创建一个车辆对象需要一分钟,因为我必须查询 8 个不同的列表/mongocollections 来获取所有信息我需要一辆车。我想知道是否有更快的方法来加入 mongocollections 或列表。

标签: c# mongodb linq csv database


【解决方案1】:

虽然我不熟悉 MongoDB,但我猜测问题在于在内存中加载了太多对象。我的方法是首先创建类来处理每个独特的数据:

public class engine
{
    public int id { get; set; }
    // other things...
}

public class maintenance
{
    public int id { get; set; }
    // other things...
}

public class Vehicle
{
    public int id { get; set; } // vehicle_id
    public engine engine { get; set; }
    public maintenance maint { get; set; }
}

然后我会使用这些类将 csv 中的辅助数据加载到字典中:

Dictionary<int, engine> engine_list = new Dictionary<int, engine>();
Dictionary<int, maintenance> maint_list = new Dictionary<int, maintenance>();

查看这些 SO 帖子以获取从 csv 数据填充 dictionarieslists 的帮助。

最后,您需要从包含大量记录的基本 csv 加载数据,使用基本文件中的 id 构造复合记录,例如engine = engine_list[id_from_csv],并将其存储在数据库中。为了有效地做到这一点,您必须将其分解为块:从基本 csv 加载 1000 条左右的记录,创建并保存记录,释放内存并处理下一个块。查看this SO 帖子,了解内存使用情况。

抱歉,我无法为您提供特定于 MongoDB 的答案;此答案假定您从 csv 开始并创建数据库记录,而不是从 MongoDB 记录开始并创建新表/记录。希望它仍然有帮助。祝你好运!

【讨论】:

    【解决方案2】:

    我发现最快的解决方案是为每种类型(车辆、查找等)创建一个包含不同表的 sql 数据库。当我刚刚加载所有数据并使用一堆连接进行查询时,它花了一分钟多的时间。但是通过创建外键引用、索引和向表中添加主键,我把它缩短到不到一秒钟。因此,我从我的 c# 代码创建查询并从每个表中取回一个包含我需要的所有信息的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 2017-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多