通过CSV在核心数据中创建2000万条记录-macOS

时间:2019-04-28 12:11:25

标签: swift macos cocoa core-data

我正在从大型CSV(4GB)构建数据库来自己为本地工作,这将不是生产应用程序。首先,我将只有一个模型/实体,其中包含8-9个属性,这些属性主要是字符串和少数几个Int。我将要存储大约2000万条记录。我将只从该CSV一次写入数据库,然后它将接收增量更新,以每月添加或修改大约50,000条记录。我将相当频繁地查询数据库,但仅以单个用户身份进行查询。

在这种情况下,核心数据是否是正确的选择?我知道这是一个对象图,而不仅仅是数据库,我有一个16GB的ram iMac和一个8GB的Macbook pro,我不确定使用Core Data时这可能有多少内存限制。我想弄清楚使用SQLite还是更好,或者Core Data是适合该工作的工具。

如果Core Data是此用例的不错选择,那么我可以在结构化记录创建方面使用一些帮助,而不必将自己限制在ram上。据我了解,我应该将实体写入子上下文,当我准备复制到磁盘时,我会将数据从子上下文传递到其父上下文(内存到内存),然后父级可以写/刷新到磁盘。

这是我将流程可视化的方式,在示例中,我将仅对实体使用一个属性。

DispatchQueue.global(qos: .background).async { //Non blocking
    //iterate line by line over csv reader never exceeds 9.1MB takes 30 mins. I will look into chunking to better utilise multithreading later.
    for (index, row) in reader.enumerated()  {
        let person = Person(entity: personEntity, insertInto: backgroundContext)
        person.setValue(row[0], forKey: "name")

        //When I hit x iterations or x seconds since last save - save to disk and clear the ram for the context 
        backgroundContext.perform {
            do {
                try backgroundContext.save() //I beleive pushes changes only to its parent context?
               //Clear background context ram (of stored records) 

               // Main context should now write to disk and then it should also clear its ram
              //do {
                  //main context work
             //} catch {

             //}
            } catch {
                //error handling 
            }
        }
    }
} 

我有两点担心,这是由于我不清楚核心数据的结构。

1)从主上下文保存到持久性存储后,我想确保主上下文可以从ram中刷新这些记录。我不想清除ram中的所有记录,因为当主上下文正在写入磁盘时(实际上是数据丢失),主上下文可能已经从后台上下文写入了。

2)与第1点类似,当保存背景上下文时,我想确保背景上下文仅清除ram中保存到其父上下文的记录。

如果有人可以阐明情况或提供一些正确结构的例子,将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找reset()类的NSManagedObjectContext函数。

但是我真的认为您在错误地使用CoreData,我建议您使用准备好的.sqlite文件(从CSV创建)初始化CoreData。与创建NSManagedObject实例并将其手动保存到上下文相比,它将更好,更快地工作。