Auf einem der letzten germany.rb-Treffen kam zwischendurch eine Frage auf, die wohl doch viele beschäftigt: was unterscheidet eigentlich die drei großen Persistenzbibliotheken ActiveRecord, DataMapper und Sequel? Ein Thema, dass schon so manchen hat fragen lassen, aber selten ordentlich beantwortet wurde. Daher will ich in einer kleinen Serie von Posts alle drei im Detail vorstellen. Dieser Post wird als Auftakt dienen und eine grobe Unterscheidung versuchen.
DataMapper und ActiveRecord beschäftigen sich beide mit Objektpersistenz. Sie versuchen also, Ruby-Objekte auf Objekte in einer Persistenzschicht (z.B. Zeilen in einer relationalen Datenbank) zu passen und dabei einen Teil der Komplexität der Datenhaltung zu verbergen. Das macht sie selbst wiederum zu sehr komplexen Gebilden.
Wer nach dem Namensgeber der beiden Bibliotheken sucht, wird sofort 2 von Martin Fowler eingeführte Persistenzmodelle finden, die sich vor allem in ihrer Abstraktionsrichtung unterscheiden. In ActiveRecord wird die Struktur der Daten zuerst einmal von der Datenbank beschrieben. ActiveRecord inspiziert dann zur Laufzeit die Datenbank, um herauszufinden, wie deren Struktur ist, um sie dann nachzubilden. Im Falle der ActiveRecord-Implementierung in Rails funktioniert das nur teilweise: da Rails auf Features von SQL-Datenbanken wie Fremdschlüssel und Constraints verzichtet, müssen Relationen zwischen ActiveRecord-Klassen immernoch von Hand angegeben werden, es ist also noch Handarbeit erforderlich.
DataMapper geht anders vor: hier werden gleich alle zu persistierenden Eigenschaften am Ruby-Objekt definiert, DataMapper kümmert sich darum diese in die Datenbank zu bringen. DataMapper inspiziert dabei die Storage nicht, kann aber bestimmte Änderungen am Store selbst vornehmen: wird an einem DataMapper-Model eine Eigenschaft hinzugefügt, kann DataMapper zum Beispiel automatisch eine Spalte in einer SQL-Datenbank hinzufügen. Selbstverständlich geschieht das nur bei nicht-destruktiven Operationen. Ein Nebeneffekt der Sache ist, dass sich dieses Konzept auch sehr leicht auf andere Datenbanken als SQL-Datenbanken übertragen lässt, weshalb DataMapper auch andere Stores ausser SQL unterstützt. DataMapper unterstützt auch von Haus die Verwendung mehrerer Datenbanken auf einmal, was zum Beispiel in Mandantensystemen sehr praktisch ist. DataMapper kann auch Relationen zwischen verschiedenen Datenstores herstellen: so kann man zum Beispiel problemlos Verbindungen zwischen Objekten ziehen, die in zwei verschiedenen Datenbanken liegen, z.B. Redis und einer SQL-Datenbank.
Jeremy Evans Sequel wird gerne mit DM und AR in einem anderen Satz genannt, hat mit ihnen aber eher wenig gemein. Sequel hat zwar als Plugin eine Objekt-Modellierungsschicht wie DataMapper und ActiveRecord, ist jedoch in dieser Hinsicht am wenigsten geeignet. Sequel legt mit seinem Namen die Marschrichtung vor: SQL, aber so richtig. Wenn man das erste Mal Sequel sieht, sieht das Ganze wie eine Alternativsyntax für SQL-Queries aus, was häufig die Frage aufwirft: “warum dann nicht gleich SQL?”. Einmal natürlich, weil SQL-Queries zusammenbauen immer ein bisschen abstrahiert gehört: einmal Quotes vergessen, schon sind die Kreditkartendaten kaputt oder für 1.50$ pro Stück irgendwo im Internet erhältlich. Zum zweiten, weil bestimmte Operationen (zum Beispiel Auswahl einer zufälligen Spalte) in verschiedenen Datenbanksystemen subtil unterschiedlich funktionieren, die man sich nicht immer merken will. Sequel bietet darüber hinaus eine ganze Reihe weiterer angenehmer Sachen: lazy queries zum Beispiel, die sich in mehreren Schritten weiter verfeinern lassen sowie viele Plugins, die das arbeiten mit reichlich diffizilen Sachen und abstrusen Datenbankfeatures erleichtern. Zwar ist Sequel ohne Plugins auf die Schnittmenge aller SQL-Datenbanken beschränkt, wer aber gerne z.B. rekursive Subqueries in Postgres verwenden will, der wird in der Plugin-Sammlung fündig. Der generierte SQL-Code ist richtig schick.
Die drei hier vorgestellten Bibliotheken sind einer der Gründe, warum ich gerne Ruby verwende: alle 3 haben einen genauen Fokus und keine ist die Kopie einer anderen. Alle drei haben ihre Stärken und Schwächen und sind einen Blick wert. ActiveRecord und DataMapper sind zum Beispiel eher schlecht im Umgang mit nicht nach ihren Vorstellungen konstruierten SQL-Datenbanken, während Sequel hier die besten Ergebnisse liefert. Umgekehrt bedeutet Sequel relativ viel Arbeit, wenn eine Applikation nur Standardfälle der anderen beiden abdeckt.
Allen dreien ist eins gemein: eine lange Entwicklungszeit und die damit erreichte Einsatzreife. Bleibt nur die Frage, was die drei jetzt genau ausmacht, die ich in weiteren Folgen beantworten werde.
Kommentar schreiben
Kommentare
danke für den artikel! ich freue mich auf die fortsetzung :=)
Oh ja, das wird eine interessante Serie!