Letzte Woche hat Realm.io Realm für Xamarin vorgestellt. Realm verspricht eine einfache Objektdatenbank mit vollständigen Abfrageoptionen und besserer Leistung als bestehende Lösungen (also auch sqlite, die wahrscheinlich am häufigsten verwendete Datenbanklösung). Es ist an der Zeit, sowohl sqlite als auch Realm auf den Prüfstand zu stellen.

Beim Vergleich dieser Lösungen wollte ich die vollen relationalen Optionen der Datenbank testen, denn damit wirbt Realm. Wenn wir nur einfache Schlüsselwerte speichern möchten, könnten wir etwas wie akavache (basierend auf dem sqlite-Backend) verwenden, das aufgrund der vielen Optimierungen bei Abfragen wahrscheinlich schneller ist. Ich empfehle die Verwendung von akavache für Caching-Szenarien oder wenn Sie nur einfache Datentypen speichern, die keine komplexen Abfragen erfordern.
Um Sqlite und Realm zu testen, habe ich ein einfaches Datenmodell mit Aufträgen und Auftragszeilen erstellt. Jeder Auftrag hat eine Liste von Auftragszeilen und ich möchte in der Lage sein, Aufträge abzufragen und die zugrundeliegenden Aufträge sofort zurückzubekommen. aber auch umgekehrt. ich möchte bestimmte Aufträge abfragen, die Auftragszeilen haben, die ein bestimmtes Produkt enthalten. diese Art von Abfragen kommen häufig vor, wenn Sie in einer realen Geschäftsanwendung arbeiten.
Jetzt haben wir also dieses Datenmodell + einige Abfragen, die wir ausführen wollen. Lassen Sie uns einige Kriterien definieren, wie wir beide Lösungen bewerten können. Ich habe mir die folgenden Kriterien ausgedacht: Benutzerfreundlichkeit, Geschwindigkeit und Wartungsfreundlichkeit.
lassen Sie uns über diese Kriterien etwas ausführlicher sprechen. Ich habe auf github ein Beispielprojekt mit Beispielen und Quellcode erstellt, mit dem Sie experimentieren können.
Sie können den Quellcode hier herunterladen: GitHub - Geertvdc/Xamarin-RealmVsSqliteCompare
Benutzerfreundlichkeit
Sqlite und Realm sind beide ziemlich einfach einzurichten. Ich habe in der Vergangenheit bereits Sqlite verwendet, aber noch nie Realm, also musste ich mich erst einmal über Realm informieren. Ich musste aber gar nicht so viel lesen, denn die grundlegende Erklärung von Xamarin.Realm auf der Realm.io Website erklärt die am häufigsten verwendeten Funktionen und alle Funktionen, die ich für diesen ersten Test benötige.
Realm ist eigentlich sehr einfach einzurichten. Während bei Sqlite ein gewisser Aufwand erforderlich ist (ein Speicherort für eine Datei zum Speichern Ihrer DB und das Erstellen einer SqlAsyncConnection), ist dies bei Realm nicht erforderlich. In Realm können Sie einfach die Methode GetInstance(); aufrufen und schon sind Sie startklar. Für beides müssen wir natürlich Nuget-Pakete installieren, was auch für Sqlite notwendig sein kann, da es so viele verschiedene Pakete gibt, dass es manchmal schwer ist, zu wissen, welche man verwenden soll.
Sqlite benötigt 3 Nuget-Pakete für die Grundfunktionalität: SQLite.Net-PCL, SQLite.Net.Core-PCL und SQLite.Net.Async-PCL. Daneben verwende ich 2 zusätzliche Pakete, die mir einige zusätzliche Erweiterungsmethoden bieten: SQLiteNetExtensions & SQLiteNetExtensions.Async.
Für Realm müssen wir nur das Nuget-Paket Realm zu allen unseren Projekten hinzufügen.
Nachdem wir eine Instanz von Sqlite und Realm erstellt haben, können wir mit dem Einfügen von Daten in unsere Datenbank beginnen. Nachfolgend finden Sie einen Beispielcode zum Einfügen von 1000 Bestellungen mit jeweils 5 Bestellzeilen. Ich möchte sie alle einfügen können und sicherstellen, dass eine Beziehung zwischen den Bestellungen und den Bestellzeilen gespeichert ist, damit ich beide in einer Abfrage abrufen kann.
Wenn man sich den Code anschaut, funktioniert Realm etwas einfacher. Wir müssen uns keine Gedanken über SQL-Transaktionen machen (wenn man die Transaktion vergisst/entfernt, ist es etwa 3x langsamer). Wir müssen nur die Objekte in einem Realm.Write-Block erstellen und Realm erledigt alles für uns. Ich muss sagen, dass ich kein Fan davon bin, dass meine Datenbankobjekte von RealmObject erben müssen und dass der Konstruktor Realm.CreateObject() sein muss, aber dazu mehr bei den Kriterien für die Wartbarkeit. Was die Benutzerfreundlichkeit anbelangt, so ist Realm einfacher, weil es die ganze Arbeit für Sie erledigt. Der Gewinner: Realm
Geschwindigkeit
Realm hat uns eine schnellere Datenbank als die Konkurrenz versprochen, und das war der Grund, warum ich diese Untersuchung begonnen habe. Sqlite kann manchmal langsam sein, aber meistens liegt das an der falschen Verwendung. Paul Betts (Schöpfer von Akavache) hat dieses Jahr auf der Xamarin Evolve eine großartige Session darüber gehalten, warum Sqlite oft langsam ist und wie man es richtig einsetzt. Um die Geschwindigkeit zu testen, habe ich eine Xamarin Forms App erstellt und einige Tests sowohl auf Android als auch auf iOS durchgeführt. Die Geschwindigkeiten variieren ein wenig von Plattform zu Plattform und es gibt auch einen gewissen Unterschied bei der Verwendung eines Geräts oder eines Emulators/Simulators. Insgesamt schien Realm bei komplexen Abfragen etwas schneller zu sein und es scheint ein gewisses Caching zu verwenden, wenn man sich die Abfrage ansieht, die auf iOS 0 ms benötigte. Eine Anmerkung hierzu ist, dass Sqlite wahrscheinlich sogar noch etwas schneller sein kann, wenn Sie die Abfragen optimieren. Was ich jetzt für Sqlite verwendet habe, ist einfach eine generische Abfrage, die alle Objekte mit ihren Unterobjekten abruft.

Nachdem ich mir die Testdaten angesehen habe, gibt es einige Unterschiede und manchmal ist Sqlite schneller als Realm und umgekehrt. Sqlite kann schnell sein, wenn Sie wissen, was Sie tun, und Realm scheint die Aufgabe recht gut zu erledigen, ohne dass Sie sich besondere Gedanken darüber machen müssen, wie man Dinge wie Transaktionen durchführt - was wiederum für die Benutzerfreundlichkeit spricht.
Der Sieger: Kein klarer Sieger zwischen Sqlite und Realm, was die Geschwindigkeit angeht
Instandhaltbarkeit
Das letzte Kriterium, nach dem ich diese 3 Lösungen testen wollte, ist die Wartbarkeit. Sicher, die Benutzerfreundlichkeit von Realm scheint gut zu sein, aber wie würde das in tatsächlichen Anwendungen funktionieren, die über lange Zeiträume hinweg gepflegt und getestet werden müssen.
Das erste, was mir beim Betrachten von Realm auffiel, war, dass alle Ihre Datenbankobjekte von RealmObject erben müssen. Aufgrund dieser Vererbung weiß Realm, wie es seine Magie einsetzen kann, aber ich mag diesen Ansatz nicht. Das Erstellen von Objekten kann nicht mit einem einfachen Konstruktor erfolgen, sondern Sie müssen immer Realm.CreateObject verwenden, um einen festen Verweis auf Realm zu erstellen. Dasselbe gilt für die Listen von Objekten innerhalb eines RealmObjects, die vom Typ RealmList<T> sein müssen. Mir gefällt Sqlites Ansatz viel besser, bei dem Sie nur einfache POCOs (Plain Old CLR Objects) mit einigen Attributen verwenden, damit Sqlite weiß, wie bestimmte Dinge zu speichern sind.
In einer vernünftigen, testbaren Softwarearchitektur sollten Sie die Abhängigkeit von Realm oder Sqlite auf ein Minimum beschränken und vorzugsweise nur in den Klassen verwenden, die die Datenbankkommunikation abwickeln. Bei Sqlite ist dies möglich, bei Realm wird dies jedoch ziemlich schwierig sein, da die Erstellung neuer Objekte nur mit Realm.CreatObject möglich ist. Sie könnten eine Zuordnung von Realm zu POCOs in Ihrem Repository vornehmen, aber das verfehlt den Zweck der Benutzerfreundlichkeit von Realm, das Funktionen für Listener bei Objektänderungen bietet, um Ihre Benutzeroberfläche einfach zu aktualisieren.
Eine weitere Sache, die Realm wirklich fehlt, ist die Unterstützung für Async. Meiner Meinung nach sollte jede mobile Bibliothek standardmäßig (oder als einzige Option) über Async-Funktionen verfügen. Es steht auf der Liste der "fehlenden Funktionen" von Realm, also ist man sich bewusst, dass dies eine wichtige Funktion ist. Aber beim derzeitigen Stand der Beta-Version ist sie noch nicht enthalten.
Das letzte, was mir aufgefallen ist, ist der Fody Weaver, der von Realm verwendet wird. Zunächst ist das für Sie als Entwickler nicht so wichtig, weil es einfach funktioniert. Der Weaver nimmt einige Änderungen an Ihrer IL vor, um Dinge hinzuzufügen, die Realm benötigt. Solange alles funktioniert, ist das kein Problem. Wenn Sie jedoch auf Probleme stoßen, haben Sie möglicherweise Schwierigkeiten, das Problem zu finden, weil der Code, der ausgeführt wird, sich von dem unterscheidet, den Sie geschrieben haben.
Wenn man diese Dinge in Bezug auf die Wartbarkeit kombiniert, ist Sqlite meiner Meinung nach ein klarer Gewinner.
Der Gewinner: Sqlite
Fazit
Wenn ich mir diese 3 Kriterien ansehe, denke ich, dass Sqlite immer noch die beste Lösung ist. Sicherlich ist Realm ziemlich schnell und benötigt fast keine Installationen, aber ich denke, dass die Wartungsfreundlichkeit von Sqlite am Ende den Sieg davontragen wird. Ich sehe durchaus einen Nutzen für Realm, insbesondere für POCs oder kleine Projekte. (Obwohl ich für POCs zu viel Erfahrung mit POCs habe, die am Ende in der Produktion laufen oder zu größeren Anwendungen wachsen, würde ich in diesem Fall Sqlite wählen).
Wir müssen berücksichtigen, dass Realm sich noch in der Beta-Phase befindet und Sqlite schon seit Ewigkeiten im Einsatz ist, aber die Dinge, die mir an Realm nicht gefallen, sind im Grunde in der Basis enthalten, so dass ich nicht glaube, dass sich das bald ändern wird. Ich werde Realm beobachten, um zu sehen, was sie in der Zukunft vorhaben, aber für den Moment werde ich weiterhin Sqlite verwenden.
Teilen Sie mir Ihre Erfahrungen mit Realm in den Kommentaren unten mit. Ich bin neugierig, ob andere Leute eine andere Meinung haben als ich, nachdem sie ein paar Tage damit gespielt haben.
Fröhliches Codieren
Geert van der Cruijsen
Die Post Xamarin-Apps: Sqlite vs. Realm. Welche ist die beste mobile DB-Lösung? erschien zuerst auf Mobile First Cloud First.
Verfasst von

Geert van der Cruijsen
Contact