Persistent Store Types

Four types of repositories are included with the Core Data API: SQLite, XML, binary, and in-memory. (XML is available only on OS X, not on iOS.) In-memory is technically not a persistent store because it is never written out to disk. Binary is effectively a serialized version of the object graph written out to disk. The XML store writes out the object graph to a human-readable text file, and SQLite stores the object graph in a relational database. When you’re working with an iOS project, it’s common to just use SQLite unless there’s a specific reason to use one of the other store formats.

Atomic Stores

Atomic stores include XML, binary, and custom data stores. All of these stores are written to disk atomically; in other words, the entire data file is rewritten on every save. Although these store types have their advantages, they don’t scale as well as the SQLite store. In addition, they’re loaded fully into memory when they’re accessed. This causes atomic stores to have a larger memory footprint than a SQLite store.

However, because they reside completely in memory while the application is running, atomic stores can be very fast, since the disk is hit only when the file is read into memory and when it’s saved back out. SQLite, although still considered a fast store, is slower when dealing with smaller data sets because of its inherent disk access. The differences are measured in fractions of a second, so we cannot expect a dramatic speed increase by using an atomic store. But if fractions of a second matter, it may be something to consider.

SQLite Persistent Store

In the most common cases, SQLite is the store option to use for application development. This is true on both iOS and OS X. SQLite is a software library that implements a self-contained, server-less, zero-configuration, transactional SQL database engine. SQLite is the most widely deployed SQL database engine in the world. The source code for SQLite is in the public domain.

Better Scaling

By utilizing a relational database as the persistent store, we no longer need to load the entire data set into memory to work with it. Because the data is being stored in a relational database, our application can scale to a very large size. SQLite itself has been tested with data sets measured in terabytes and can handle just about anything that we can realistically develop. Since we’re loading only the data we want at a particular moment, SQLite keeps the memory footprint of our application quite low. Likewise, SQLite makes efficient use of its disk space and therefore has a small footprint on disk as well.

More Performance-Tuning Options

By working with a database instead of a flat file, we have access to many more performance-tuning options. For example, we can index the columns within our entities to enable faster predicates. We can also control exactly what gets loaded into memory. It’s possible to get just a count of the objects, just the unique identifiers for objects, and so on. This flexibility allows us to tune the performance of our application more than any other store type. Because the SQLite store is the only format that’s not fully loaded into memory, we get to control the data flow. All of the other formats require that the entire data file be loaded into memory before they can be used. The details of how to utilize these features are discussed in Fetching.