NoSQL databases
Sometimes being unstructured helps
Amrit Sanjeev
Organizer @ Blrdroid
Who am I ?
Agenda
● Type of databases available in Android
● When to use them
● How they help ?
● Some feature of popular db products
Data trends
- Amount of data stored is increasing
- Data is more unstructured
- Efficiency and performance are critical
- Relations are more complex
Datastore evolution
RDBMS vs NoSQL
- Structured data
- Transform data policy
- Atomic transactions
- Data model != Entity model
- Scale up
- Semi or unstructured data
- Update schema policy
- Eventual consistency
- Data model ~= Entity model
- Scale out
Real time database
- NoSQL, JSON database
- Maps each piece of data to a URL
- Offline support
- Supports iOS , Android and Web
- Pushes updates in milliseconds when
things change
Cross platform support
Listening to data changes
● Attach an asynchronous listener to a Firebase reference.
● The listener will be triggered
○ once for the initial state of the data
○ again anytime the data changes
Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue());
}
@Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
Reading data once
● Callback will be called only once
● removed after the first trigger
Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
// do some stuff once
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Querying data
● Selectively retrieve data based on various factors.
● Start by specifying how you want your data to be ordered
○ orderByChild()
○ orderByKey()
○ orderByValue()
○ orderByPriority()
● combine these other methods to conduct complex queries
○ limitToFirst()
○ limitToLast()
○ startAt()
○ endAt()
○ equalTo()
What is Realm ?
- Zero copy object store database
- Easy setup
- Optimized for read , not writes
- Cross platform
- Simple Querying interface
Defining objects in realm
public class Person extends RealmObject {
@PrimaryKey
private long id;
private String name;
private RealmList<Dog> dogs;
// Declare one-to-many relationships
// ... Generated getters and setters ...
}
@RealmClass
public class Person implements RealmModel {
@PrimaryKey
private long id;
private String name;
private RealmList<Dog> dogs;
// Declare one-to-many relationships
// ... Generated getters and setters ...
}
Relationships
public class Person extends RealmObject {
private String firstName;
private String lastName;
private Dog dog;
// ... Generated getters and setters ...
}
public class Person extends RealmObject {
private String firstName;
private String lastName;
private RealmList<Dog> dogs;
// ... Generated getters and setters ...
}
public class Person extends RealmObject {
private String firstName;
private String lastName;
private RealmList<Person> friends;
// .. getters/setters
}
Saving objects in realm
// Use them like regular java objects
Dog dog = new Dog();
dog.setName("Rex");
dog.setAge("1");
// Get a Realm instance
Realm realm = Realm.getDefaultInstance();
// Persist your data easily
realm.beginTransaction();
realm.copyToRealm(dog);
realm.commitTransaction();
// Get a Realm instance
Realm realm = Realm.getDefaultInstance();
// Create and persist your data easily
realm.beginTransaction();
Dog dog = realm.createObject(Dog.class);
dog.setName("Rex");
dog.setAge("1");
realm.commitTransaction();
Transactions
try {
realm.beginTransaction();
Dog dog = realm.where(Dog.class).
equalTo("name", "Fido").findFirst();
dog.setAge(15);
realm.commitTransaction();
}
catch (Exception ex) {
// rollback
realm.cancelTransaction();
}
realm.executeTransaction(
new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Dog dog= realm.where(Dog.class).
equalTo("name", "Fido").findFirst();
dog.setAge(15);
}
})
Async Transactions
// Use them like regular java objects
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm bgRealm) {
User user = bgRealm.createObject(User.class);
user.setName("John");
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
// Transaction was a success.
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
// Transaction failed and was automatically canceled.
}
});
RealmAsyncTask transaction = realm.executeTransactionAsync(
new Realm.Transaction() {
@Override
public void execute(Realm bgRealm) {
User user = bgRealm.createObject(User.class);
user.setName("John");
user.setEmail("john@corporation.com");
}
}, null);
Querying data
// Build the query looking at all users:
RealmQuery<User> query = realm.where(User.class);
// Add query conditions:
query.equalTo("name", "John");
query.or().equalTo("name", "Peter");
// Execute the query:
RealmResults<User> result1 = query.findAll();
// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults<User> result2 = realm.where(User.class)
.equalTo("name", "John")
.or()
.equalTo("name", "Peter")
.findAll();
Query data supports
- Conditions like lessThan, greaterThan, contains, beginsWith etc
- Modifiers for ignoring Cases
- Logical Operations OR AND
- Sorting Ascending, Descending
- Chaining Queries
- Aggregations like SUM, MIN, MAX, AVG
- Synchronous, Asynchronous operations
Linked queries
public class Person extends RealmObject {
private String id;
private String name;
private RealmList<Dog> dogs;
// getters and setters
}
public class Dog extends RealmObject {
private String id;
private String name;
private String color;
// getters and setters
}
Linked queries
RealmResults<Person> r1 = realm.where(Person.class)
.equalTo("dogs.name", "Fluffy")
.findAll();
RealmResults<Person> r2 = r1.where()
.equalTo("dogs.color", "Brown")
.findAll();
Auto updating objects
Dog d1 = realm.where(Dog.class).equals("id", 123).findFirst();
// register a listener to get notified when the object is updated.
d1.registerChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
// called once the query complete and on every update
// do something now that the obj is updated
}
});
// assume code below is in some other thread
// Retrieve the same dog as above
Dog d2 = realm.where(Dog.class).equals("id", 123).first();
realm.beginTransaction();
d2.setAge(12);
realm.commitTransaction();
// d1's change listener gets called after the commit.*
Migration
// Example migration adding a new class
RealmMigration MyMigration = new RealmMigration() {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
// DynamicRealm exposes an editable schema
RealmSchema schema = realm.getSchema();
if (oldVersion == 0) {
schema.create("Person")
.addField("id", long.class, FieldAttribute.PRIMARY_KEY)
.addField("name", String.class)
.addField("age", int.class);
oldVersion++;
}
}
}
// in your init
RealmConfiguration config = new RealmConfiguration.Builder(context).schemaVersion(1)
.migration(new MyMigration()) ;
More features
● Direct support for Json to Object store
● Notification for database change like CP
● Encryption support in built
● Adapters for binding data with views (Android)
● Cross Platform, same data can work across ios and android
● Robust 3rd parties addons
Limitations
● Managing memory is tricky
● Not Entirely NOSQL, need migration on schema Changes
● No support for auto incrementing primary keys
● Mutable, thread-confined objects.
● Slower write
● Increase method count and size of apk
Latest update
● Server side tech
○ Real time sync
○ Conflict resolution
○ Reactive event handling
○ Authentication
○ Access control
● Good to building offline experiences
● Not a managed service yet
Thank you!
Amrit Sanjeev
@amsanjeev
#blrdroid

No sql databases blrdroid devfest 2016

  • 1.
    NoSQL databases Sometimes beingunstructured helps Amrit Sanjeev Organizer @ Blrdroid
  • 2.
  • 3.
    Agenda ● Type ofdatabases available in Android ● When to use them ● How they help ? ● Some feature of popular db products
  • 4.
    Data trends - Amountof data stored is increasing - Data is more unstructured - Efficiency and performance are critical - Relations are more complex
  • 5.
  • 6.
    RDBMS vs NoSQL -Structured data - Transform data policy - Atomic transactions - Data model != Entity model - Scale up - Semi or unstructured data - Update schema policy - Eventual consistency - Data model ~= Entity model - Scale out
  • 8.
    Real time database -NoSQL, JSON database - Maps each piece of data to a URL - Offline support - Supports iOS , Android and Web - Pushes updates in milliseconds when things change
  • 9.
  • 10.
    Listening to datachanges ● Attach an asynchronous listener to a Firebase reference. ● The listener will be triggered ○ once for the initial state of the data ○ again anytime the data changes Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts"); ref.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { System.out.println(snapshot.getValue()); } @Override public void onCancelled(FirebaseError firebaseError) { System.out.println("The read failed: " + firebaseError.getMessage()); } });
  • 11.
    Reading data once ●Callback will be called only once ● removed after the first trigger Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts"); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { // do some stuff once } @Override public void onCancelled(FirebaseError firebaseError) { } });
  • 12.
    Querying data ● Selectivelyretrieve data based on various factors. ● Start by specifying how you want your data to be ordered ○ orderByChild() ○ orderByKey() ○ orderByValue() ○ orderByPriority() ● combine these other methods to conduct complex queries ○ limitToFirst() ○ limitToLast() ○ startAt() ○ endAt() ○ equalTo()
  • 14.
    What is Realm? - Zero copy object store database - Easy setup - Optimized for read , not writes - Cross platform - Simple Querying interface
  • 15.
    Defining objects inrealm public class Person extends RealmObject { @PrimaryKey private long id; private String name; private RealmList<Dog> dogs; // Declare one-to-many relationships // ... Generated getters and setters ... } @RealmClass public class Person implements RealmModel { @PrimaryKey private long id; private String name; private RealmList<Dog> dogs; // Declare one-to-many relationships // ... Generated getters and setters ... }
  • 16.
    Relationships public class Personextends RealmObject { private String firstName; private String lastName; private Dog dog; // ... Generated getters and setters ... } public class Person extends RealmObject { private String firstName; private String lastName; private RealmList<Dog> dogs; // ... Generated getters and setters ... } public class Person extends RealmObject { private String firstName; private String lastName; private RealmList<Person> friends; // .. getters/setters }
  • 17.
    Saving objects inrealm // Use them like regular java objects Dog dog = new Dog(); dog.setName("Rex"); dog.setAge("1"); // Get a Realm instance Realm realm = Realm.getDefaultInstance(); // Persist your data easily realm.beginTransaction(); realm.copyToRealm(dog); realm.commitTransaction(); // Get a Realm instance Realm realm = Realm.getDefaultInstance(); // Create and persist your data easily realm.beginTransaction(); Dog dog = realm.createObject(Dog.class); dog.setName("Rex"); dog.setAge("1"); realm.commitTransaction();
  • 18.
    Transactions try { realm.beginTransaction(); Dog dog= realm.where(Dog.class). equalTo("name", "Fido").findFirst(); dog.setAge(15); realm.commitTransaction(); } catch (Exception ex) { // rollback realm.cancelTransaction(); } realm.executeTransaction( new Realm.Transaction() { @Override public void execute(Realm realm) { Dog dog= realm.where(Dog.class). equalTo("name", "Fido").findFirst(); dog.setAge(15); } })
  • 19.
    Async Transactions // Usethem like regular java objects realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm bgRealm) { User user = bgRealm.createObject(User.class); user.setName("John"); } }, new Realm.Transaction.OnSuccess() { @Override public void onSuccess() { // Transaction was a success. } }, new Realm.Transaction.OnError() { @Override public void onError(Throwable error) { // Transaction failed and was automatically canceled. } }); RealmAsyncTask transaction = realm.executeTransactionAsync( new Realm.Transaction() { @Override public void execute(Realm bgRealm) { User user = bgRealm.createObject(User.class); user.setName("John"); user.setEmail("john@corporation.com"); } }, null);
  • 20.
    Querying data // Buildthe query looking at all users: RealmQuery<User> query = realm.where(User.class); // Add query conditions: query.equalTo("name", "John"); query.or().equalTo("name", "Peter"); // Execute the query: RealmResults<User> result1 = query.findAll(); // Or alternatively do the same all at once (the "Fluent interface"): RealmResults<User> result2 = realm.where(User.class) .equalTo("name", "John") .or() .equalTo("name", "Peter") .findAll();
  • 21.
    Query data supports -Conditions like lessThan, greaterThan, contains, beginsWith etc - Modifiers for ignoring Cases - Logical Operations OR AND - Sorting Ascending, Descending - Chaining Queries - Aggregations like SUM, MIN, MAX, AVG - Synchronous, Asynchronous operations
  • 22.
    Linked queries public classPerson extends RealmObject { private String id; private String name; private RealmList<Dog> dogs; // getters and setters } public class Dog extends RealmObject { private String id; private String name; private String color; // getters and setters }
  • 23.
    Linked queries RealmResults<Person> r1= realm.where(Person.class) .equalTo("dogs.name", "Fluffy") .findAll(); RealmResults<Person> r2 = r1.where() .equalTo("dogs.color", "Brown") .findAll();
  • 24.
    Auto updating objects Dogd1 = realm.where(Dog.class).equals("id", 123).findFirst(); // register a listener to get notified when the object is updated. d1.registerChangeListener(new RealmChangeListener() { @Override public void onChange() { // called once the query complete and on every update // do something now that the obj is updated } }); // assume code below is in some other thread // Retrieve the same dog as above Dog d2 = realm.where(Dog.class).equals("id", 123).first(); realm.beginTransaction(); d2.setAge(12); realm.commitTransaction(); // d1's change listener gets called after the commit.*
  • 25.
    Migration // Example migrationadding a new class RealmMigration MyMigration = new RealmMigration() { @Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); if (oldVersion == 0) { schema.create("Person") .addField("id", long.class, FieldAttribute.PRIMARY_KEY) .addField("name", String.class) .addField("age", int.class); oldVersion++; } } } // in your init RealmConfiguration config = new RealmConfiguration.Builder(context).schemaVersion(1) .migration(new MyMigration()) ;
  • 26.
    More features ● Directsupport for Json to Object store ● Notification for database change like CP ● Encryption support in built ● Adapters for binding data with views (Android) ● Cross Platform, same data can work across ios and android ● Robust 3rd parties addons
  • 27.
    Limitations ● Managing memoryis tricky ● Not Entirely NOSQL, need migration on schema Changes ● No support for auto incrementing primary keys ● Mutable, thread-confined objects. ● Slower write ● Increase method count and size of apk
  • 28.
    Latest update ● Serverside tech ○ Real time sync ○ Conflict resolution ○ Reactive event handling ○ Authentication ○ Access control ● Good to building offline experiences ● Not a managed service yet
  • 29.