What SQLite library do you recommend on the iPhone/iPad? - iphone

A few people have wrapped the SQLite library or provided alternatives. What are their relative merits?

Core Data
Yes, a bit of snarky answer.
There are three primary reasons to use SQLite directly or via a wrapper.
You are sharing databases across platforms and can't use Core Data's schema
You really do need raw SQLite performance and have the 17th level SQLite API Mastery required to actually achieve said performance advantage over SQLite.
You know SQLite inside and out, don't like learning new things, and want to re-invent the bits necessary to get between database and screen. (Slightly snarky again).
Core Data buys you a tremendous amount of functionality that is subtly very hard to do. That is, object graph management with full integrity and undo support.

bbum gave the most succinct answer and you should ponder carefully not using Core Data.
But I thought you also deserved an answer to your actual question.
There are basically two wrapper approaches I know of:
FMDB uses an approach that simply makes a much easier to use Cocoa API overlay for SQLLite. This can be great if you know SQL and database design well and just want a simple database.
Other approaches are generally more object-relational mapping systems, that attempt to give you an object view of an underlying datastore, and hide some queries from you.
In both cases if you have a really simple data store they can make sense to use if you have a specific reason... but using Core Data gives you an awful lot for free (though I'll admit the learning curve can be steep).

There is a third approach. This third approach allows you to build SQLite statements via a set of Objective-C classes. They will handle how your data is converted and sanitized. They will also ensure that your statements are correctly constructed. You can try https://github.com/ziminji/objective-c-sql-query-builder This particular library also offers Object Relational Mapping (ORM) that follows the Active Record design pattern.

Related

Core Data VS Sqlite or FMDB....?

Now this might look like a duplicate thread, but my question is that I have read a lot of questions like.. Core Data vs SQLite 3 and others but these are 2-3 years old. I have also read that FMDB was developed as core data was not supported on iOS, So it should not be used any more. And on the other hand I have read that one should not use core data as a database.
So I am seriously confused,whether I should use core data for object storage or not. I mean on what basis I should decide which to use? Are there any guidelines provided by apple or someone else.. or is it something that will come to me with time.?
Ankit,
Here's the tl;dr skinny: use Core Data.
Here's the long form:
While you could use many criteria to choose between Core Data, an ORM (FMDB) or direct sqlite calls, the real cost of this choice comes from your time to use it, Apple's support and leverage from other projects. (RESTKit, which maps REST services on to Core Data, is popular these days.)
Hence, a large percentage of the time, say 90+% (a made up stat), the answer on iOS will be to use Core Data. Why? Once you get the hang of it and build out a few little helper methods, Core Data keeps you in a consistent computing world -- the Objective-C object graph. Core Data will teach you things about how to use a dynamic language that will help every other aspect of your iOS programming. Hence, you are more productive. Don't fight the framework.
If you are bringing over a large, complex SQLite database & schema from another app, it then might be cost effective to use either FMDB or SQLite. But I doubt it. Your time writing a simple Mac-based command line app to migrate the DB to a Core Data DB is a finite and simple task. You are almost guaranteed to have to rewrite most of the business logic in Objective-C. (Yes, C++ and Objective-C++ are both good technologies. Has your database business logic really been tuned to work on a memory limited device? I didn't think so.)
Core Data gets a bum rap on performance. It is really quite fast. You just have to use it differently than you use a DB. In particular, you almost always over-fetch data from the store and then refine it using predicates directly on the various sets and arrays. On iOS devices, where the flash is surprisingly slow, this over-fetch strategy is particularly effective. You actually have a lot of RAM on these devices, use it to gain performance. (Yes, I know this is an apparent contradiction to my above knock on portable business logic. But really, code ported from a desktop or server environment has so many implicit assumptions about the speed of the disk, the amount of memory and the reality of a VM with a backing store, it just will not work well on a battery powered, memory limited device with a funky memory model. [It won't work very well on Android devices either.]) You will also denormalize your data to simplify displaying it in various iOS and Mac OS X UI widgets. There are a few applications where Core Data will be slower than an equivalent SQLite DB. Those have been detailed elsewhere. The one major claim is that tasks where IDs are defined by upstream databases hits Core Data's performance is true. But it can be somewhat mitigated by judicious indexing and over-fetching.
The thing to remember about mobile devices too is that the database size, because these are mobile devices on the leaves of the internet, is generally of modest size. Hence, performance is easier to attain. Many lessons from the world of servers may not apply to this mobile, battery powered world.
In other words, you've had to go "all in" to use Objective-C on iOS/Mac OS X, you will gain some important productivity benefits from using Core Data too.
Andrew
I recently embarked on this journey myself, and ended up trying out all three. Here's what I learned:
Raw sqlite3
Low-level, full access to database. No abstractions. Very verbose - it takes a good deal of code to do very simple things.
Core Data
Very high-level, built on abstractions, MUST use Apple's generated database. Useful for iCloud synchronization and simple iOS-only data management. Difficult and dangerous to directly access database, and should not be used for cross-platform databases. Still takes a fair amount of code to do simple things.
FMDB
High-level, very abstraction friendly but not forced. Still get full access to database if you need it. Provides an NSDictionary of the result with each item automatically typecasted to the mutable variant of the proper datatype (e.g., text columns are returned as NSMutableString). I ended up building a very simple wrapper class around it to abstract it even more, so I have a helper class with static functions like selectAllFrom:(NSString *)table where:(NSDictionary *)conditions, which returns an NSArray of NSDictionary objects. It's fantastic to be able to do things like NSArray *usersNamedJoe = [DBHelper selectAllFrom:#"user" where:#{#"name": #"Joe"}];.
Basically, while Core Data may be useful for simple iOS-only apps, anyone who's interested in using cross-platform databases should stay far, far away from it - Apple has no interest in making that easy, and it shows.
TL;DR:
Don't use raw sqlite3 unless you're doing something extremely trivial.
Core Data is fine for simple iOS-only data, if you're comfortable with being locked into it.
If you want full control over the database and you're not doing something trivial, or you're building your app for multiple platforms, FMDB is definitely the way to go.
I use FMDB for all my projects that have heavy usage of "INSERTs" and FMDB is not out of date. The last commit on Github was at last November. If you go with SQL I recommend you to use FMDB.
Core Data fits to 95% of all projects, but if it comes to optimization to run to a wall. If you want the benefits of Core Data (OOP, ...) then use it. If you have a lot of insert an deletes with "WHERE" user Sqlite (FMDB)
This POST explain the off and top site for Core Date vs. Sqlite (FMDB)
CoreData is not just an abstraction of an SQL database. CoreData is also does object graph management. CoreData can do things that FMDB simply can't do.
As always: It really depends on your use case. But in 99% of cases CoreData is the right choice.
If performance is critical, you still have to understand how a database works. But CoreData can deliver that performance if you use it the right way. But it takes some time to learn. There are many things that are trivial to do in CoreData that would be very complex to do in FMDB.
As a new SQL guy, I'm going to throw in my two cents:
In Core Data, you have a bit of "boilerplate" code that you need to put in before you can actually use your database. Your app needs at least one of these:
A persistent store coordinator
A managed object context
A managed object. This correlates to an entity, which correlates to a table if you use an SQLite database.
To take full advantage of the framework, you need to understand what role these objects play in the management of your data.
On the other hand, we have SQLite, which - in my opinion - is much easier to understand. To start, you'll need:
A database
A table or more (depending on your data)
Knowledge of SQL - a flexible language with a simplistic syntax (SELECT queries do more than what you might originally think they do)
An object through which your app communicates with SQLite.
Core Data is only an object abstractization of the SQLite3 database. That means you'll have persistant objects easy to manage for standard database operations. You can also work in an transactional mode and design your core data database structure in XCode by creating models.
If you don't whant to create manually your SQLite3 database or persistant methods use Core Data.

Why is Core Data so difficult to prepopulate?

This is a more a philosophical question about Apple's design decisions than a question about Core Data.
Why in the world is it useful to have a model system that is so difficult to prepopulate? What are the advantages? I know you can have your program generate the sqlite file and edit it manually, but as far as I can tell, you can't do that if you have any relationships at all.
I compare this to the MVC paradigm used in rails, which seems to make way more sense. Models in rails provide a similar level of abstraction to Core Data (from what I can tell) but they also allow you to enter whatever you want into your database manually (or through a script).
The problem I have with Core Data is that: since rails seems to prove (to me) that you can have an excellent model abstraction from the database while retaining several convenient methods to prepopulate it, what possible advantages does removing that ability offer? Is Core Data somehow more efficient? Is the difficulty involved in prepopulation merely a side-effect of other design choices, and if so, why wasn't prepopulation taken into consideration?
(A disclaimer that I'm genuinely interested in the reasoning behind these choices, and though my post might suggest it, I'm not really looking for a "Models in Rails vs. Core Data" debate.)
Because Core Data is NOT a database. It is an object graph that happens to persist to disk and one of those persistence formats is a database. This means you need to look at it in a reverse PoV.
Core Data is designed to be as fast as possible in retrieving objects from that persistent store and saving them back out. One side effect of this is that the persistent format is focused on making that goal faster and being compatible with anything else is secondary at best. Thus the internal structure of the SQLite file is aimed at performance, not at compatibility.
My opinion about pre-population is that Core Data is designed as a closed loop system. You can use Core Data to populate the data file easily. It is no harder to populate a Core Data SQLite file than it is to write a script to translate your Oracle data to CSV format.
If you stay within Cocoa and Core Data then it is not difficult at all. You write a command line app or editing app and import the data. From the PoV of a Cocoa programmer, that is a trivial task that takes just a few minutes.

Core Data VS SQL Statement, which one is gd for iphone development?

iPhone 3.0 support the Core Data, it seems a great tool for developer. But SQL statement seems it is easier to get start, but core data is easier for maintaining db. But I'm considering the SQL statement, because it seems have better performance. I am consider which one is better for iPhone development, any suggestion?
The answer is actually much simpler than either of those blog posts make it appear. The rule is:
If you are developing for any OS X platform;
If you are not accessing a proprietary format; and
If your persistence file does not need to be read on a non OS-X platform
Then you should go with Core Data. It is that simple. Core Data gives you so many features and the ease of use compared to straight SQL makes the choice simple. As far as performance, that is a red herring. Where it counts, Core Data can and does easily out perform custom code accessing a SQLite database. However, performance on Cocoa Touch is actually a secondary concern.
The primary concern is memory. You have a tiny amount of memory in which to work with on Cocoa Touch and your data model can easily blow that out. Core Data solves that issue. It watches how much memory it is using and will drop objects out of memory automatically when it receives a memory warning. All of that fairly complex code you would have to write yourself if you used SQLite directly.
Less time coding your data model means you have more time making your application great.
This provides a reasonable list of the pros and cons of either approach: http://maniacdev.com/2009/09/iphone-sqlite-vs-core-data-–-which-to-choose/
The recommendation is to use Core Data as it makes things so much easier in the long term.
There is an in-depth explanation of the differences between the 2 here: http://cocoawithlove.com/2010/02/differences-between-core-data-and.html
That's a great read. The 2 approaches are different and both have their pros and cons.

Core Data vs. SQLitePersistentObjects

I'm creating an iPhone app and I'm trying to choose between 2 solutions for a persistent store.
Core Data, or SQLitePersistentObjects. Basically, all my app needs is a way to store an array of model objects and then load them again to display in a UITableView. Its nothing too complicated. Core Data seems to have a much higher learning curve than the simple to use SQLitePersistentObjects. Are there any obvious benefits of using Core Data over SQLitePersistentObjects in my case?
As the author of SQLite Persistent Objects, I say: use Core Data.
I wrote SQLPO when Core Data didn't exist on the phone. Although I'm proud of what I did with SQLPO and even though I do like some things about its approach better than Core Data's (specifically not having to maintain separate class files and data model), the engine underlying Core Data is much more mature and has many more engineering hours invested in it. That's why I abandoned SQLPO development when Core Data came to the iPhone SDK.
I haven't done benchmarks, but I would guess that used correctly, Core Data is going to perform better in nearly all high-volume situations.
SQLPO is faster to develop with since all you do is create the header files, but unless your data needs are relatively light, I say you'd be better off using Core Data.
See this question. My answer to that question also applies to yours.
Core Data VS SQL Statement, which one is gd for iphone development?
Some infromation on my experience with SQLitePersistentObjects.
An app initially developed for iOS 3.x utilizing SQLPO works just fine. Easy to use etc.
Now I am in the process of bringing this app to iOS 4 and things started to get strange.
I now see DB corruptions at unpredictable rates.
Looking into the SQLPO code shows that there is only one sqlite3_close statement and this is called when the DB can not be opened.
I am planning to add a method to close the DB explicitely and call this from my app delegates terminate and for iOS4 didMovetoBackground methods.
Might help to avoid DB corruption issues with SQLPO.
I recently had to make the same decision. I was storing instances of a simple object with a couple of properties. From my research I understand that using Core Data will help you better manage more complex objects with multiple relationships. I ended up using Core Data only because I wanted to learn more about it (but for simple objects there wasn't much of a learning curve).
SQLitePersistentObjects aka SQLLite Persistent Objects is not the same as doing straight SQLite at all. It's an ORM in its own right. I haven't used it yet, but I wanted to correct the completely wrong answer that the previous poster gave.
And I'm seriously considering using because Core Data is a pain.
See: http://iphonedevelopment.blogspot.com/2008/08/sqlite-persistent-objects.html

Has anyone tried any of the SQLite3 wrapper APIs for easier database functionality on the iPhone?

Coming from a non-SQL background, I've been having a hard time absorbing SQLite3 for the past few days. Has anyone had any good results using any of the SQLite3 wrapper APIs out there? Do they work reliably? Which is best? I am also hearing buzz about Core Data coming to the iPhone. Not sure whether that info is trustworthy or not but maybe some of you know: will there be a Core Data for the iPhone at some point?
FMDB is easy to use and abstracts some of the SQLite nastiness away from you, but still exposes the SQL.
I have used it in a project, but subclassed it to add my own partially-OO layer. The advantage of this approach is that if I need more speed or something I did not foresee (triggers for example), I can make it happen. With Core Data, there is no "bypassing" available and I have to rely on Core Data's optimizations, memory use, etc.
Another difference is the Core Data will allow your app to remain fully OO. With FMDB or other database solution, you're always tied closely to the organization of the database. It's a design decision, and not one you can change later.
If you're only just starting now, I would use Core Data.
I spent some time last year looking at the various wrappers at the time. I didn't use any of them in the end.
I think the NDA was still in place when I was looking so I may have missed the best ones, but I found that most were very thin wrappers. For my purposes this meant that it added an external dependency, didn't save much typing and I would probably still have had to dive down to using sqlite function calls sometimes anyway. Just didn't seem worth it.
Why not target CoreData using the 3.0 SDK?
If for some reason you need to support 2.x, you should look at SQLitePersistentObject. It's slow and has some bugs but it is VERY easy to use. Sadly it is no longer under active development by the author.
Additionally:
Some time ago, with a small sample project (2.x) I used fmdb. As far as I remember it was pretty easy to use. However, it required SQL knowledge.