Создание 20 миллионов записей в Core Data из CSV - macOS - PullRequest
0 голосов
/ 28 апреля 2019

Я создаю базу данных из большого CSV (4 ГБ) для локальной работы, это не будет производственным приложением.Для начала у меня будет только одна модель / сущность, которая содержит 8-9 атрибутов, которые в основном представляют собой строки и несколько Int.У меня будет около 20 миллионов записей для хранения.Я буду писать базу данных из этого CSV только один раз, и с этого момента она будет получать дополнительные обновления, чтобы добавлять или изменять примерно 50 000 записей в месяц.Я буду опрашивать базу данных довольно часто, но только как один пользователь.

Является ли Core Data правильным выбором для этого сценария?Я понимаю, что это граф объектов, а не просто база данных, у меня есть iMac на 16 ГБ и MacBook Pro на 8 ГБ, и я не уверен, какое ограничение памяти это может иметь при использовании Core Data.Я пытаюсь выяснить, будет ли мне лучше использовать SQLite или Core Data является правильным инструментом для работы.

Если Core Data является хорошим выбором для этого варианта использования, тогда я мог бы использовать некоторую помощь поструктурирование создания записей, не ограничивая себя оперативной памяти.Насколько я понимаю, я должен записывать сущности в дочерний контекст, и когда я буду готов к копированию на диск, я передам данные из дочернего контекста в его родительский контекст (память в память), а затем родитель может записать / сбросить на диск,

Вот как я бы визуализировал процесс, я буду использовать только один атрибут на примере объекта.

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) После сохранения в постоянном хранилище из основного контекста я хочу убедиться, что основной контекст может очистить эти записи от оперативной памяти.Я не хочу очищать все записи в оперативной памяти, так как основной контекст мог быть записан из фонового контекста, в то время как основной контекст записывал на диск (фактически потеря данных).

2) Как и в пункте 1, когда фоновый контекст сохраняется, я хочу убедиться, что фоновый контекст очищает только записи из оперативной памяти, которые были сохранены в его родительском контексте.

Если кто-то может сбросить некоторыеОсветите ситуацию или приведите несколько примеров правильной структуры, это было бы очень полезно.

Спасибо,

1 Ответ

1 голос
/ 28 апреля 2019

Я думаю, что функция reset() класса NSManagedObjectContext - это то, что вы ищете.

Но я действительно думаю, что вы используете CoreData неправильно, я бы предложил вам запустить CoreData с подготовленным файлом .sqlite (созданным из CSV).Он будет работать лучше и намного быстрее, чем создавать экземпляры NSManagedObject и сохранять их в контексте вручную.

...