Beyond SQLite & Core Data
NoSQL for Mobile
Sam Ritchie
App Data Storage
iOS Data Storage
0%
5%
10%
15%
20%
Core Data SQLite FMDB
Android Data Storage
0%
5%
10%
15%
20%
SQLite ormlite greenDAO
So What?
Logical model
Arbitrary queries
Concurrency
Tool support
Existing skills
!
!
!
!
Replication
Full Text indexing
Spatial indexing
Schema upgrades
Object-Relational impedance
Relational DatabasesDatabases
NoSQL
Order
Order
Order
Customer
Customer
Customer
Order Line
Order Line
Order Line
Product
Product
Product
Order
Customer
Order Line
Product
Order Line
Product
Order Line
Product
Order
Order
Order
Customer
Customer
Customer
Order Line
Order Line
Order Line
Product
Product
Product
Order
Order
Order
Customer
Customer
Customer
Order Line
Order Line
Order Line
Product
Product
Product
Order Line
OrderOrder
Customer
Customer
Product
Order +
Order
Order Line
Order Line
Order
Order Line
Product
Order Line
Product
Order Line
Product
Customer
Order
Customer
Order Line
Product
Order Line
Product
Order Line
ProductProduct
Customer
!
Options?
The File System
YapDatabase
Benchmarks
{ title : …, body : …, createdDate : …, ownerId : “users/1234”, ownerDisplayName : “Sam”, … answers : [ { score : …, body : …, ownerId : “users/4567”, ownerDisplayName : “Jon Skeet”, comments : [] }], comments : [ { score : …, text : …, ownerId : “users/1234”, ownerDisplayName : “Sam” }], tags : [ “objective-c”, “iOS” ], duplicates : [ “questions/456” ], related : [] }
questions/123 users/1234{ displayName : “Sam” reputation : 1337, profileImageURL : …, websiteURL : …, age : …, location : …, creationDate : …, lastAccessDate : … }
Fetch Tag Counts Full Text Search LOC
Core Data CouchBase Lite YapDatabase LevelDB
Awesome
Crap
Cost of Abstraction
CBLQuery *query = [[self.database viewNamed:@"tags"] createQuery]; query.groupLevel = 1; for (CBLQueryRow *row in [query run:NULL]) NSLog(@"%@ (%@)", row.key, row.value);
Couchbase Lite
__block NSString *currentTag = nil; __block int count = 0; [database enumerateKeysWithPrefix:@"i/tags/" block:^(NSString *key, BOOL *stop) { NSString *tag = [[key stringByDeletingLastPathComponent] stringByReplacingOccurrencesOfString:@"i/tags/" withString:@""]; if (!currentTag || ![currentTag isEqualToString:tag]) { NSLog(@"%@ (%d)", currentTag, count); count = 0; currentTag = tag; } count++; }]; NSLog(@"%@ (%d)", currentTag, count);
LevelDB
Cost of Abstraction
select name, count(1) from Tags group by name
NSFetchRequest* fetch = [NSFetchRequest fetchRequestWithEntityName:@"Tag"]; NSEntityDescription* entity = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:self.context]; NSAttributeDescription* nameDesc = [entity.attributesByName objectForKey:@"name"]; NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"name"]; NSExpression *countExpression = [NSExpression expressionForFunction: @"count:" arguments: [NSArray arrayWithObject:keyPathExpression]]; NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName: @"count"]; [expressionDescription setExpression: countExpression]; [expressionDescription setExpressionResultType: NSInteger32AttributeType]; [fetch setPropertiesToFetch:[NSArray arrayWithObjects:nameDesc, expressionDescription, nil]]; [fetch setPropertiesToGroupBy:[NSArray arrayWithObject:nameDesc]]; [fetch setResultType:NSDictionaryResultType]; NSError* error = nil; NSArray *results = [self.context executeFetchRequest:fetch error:&error]; for (NSDictionary *result in results) NSLog(@"%@ (%@)", result[@"name"], result[@"count"]);
Core Data
Live Coding Demo
Questions?
mailto:[email protected]Top Related