Ist ORM ein schlechtes Werkzeug für baumartige DB-Strukturen?

8

Ich weiß, dass diese Frage möglicherweise als meinungsbasiert geschlossen wird, aber was ich jetzt brauche, sind einige Meinungen, die durch Argumente gestützt werden.

Ich erstelle eine Anwendung mit Postgres und Ecto (Elixier) als Persistenzschicht. Es gibt eine Entität, die auf sich selbst verweist, sodass Sie damit eine baumartige Struktur erstellen können. Je mehr ich versuche, dies mit Ecto zu tun, desto frustrierter werde ich.

Sind ORMs einfach ein schlechtes Werkzeug zum Erstellen komplexer DB-Strukturen mit vielen Assoziationen? Die objektorientierte Art und Weise, wie ORM versucht, relationale Daten durchzusetzen, scheint hier ein schlechter Ansatz zu sein. Objekte sind isoliert. Wenn sie mit anderen Objekten interagieren, senden sie Nachrichten. Ihre inneren Details sollten verborgen bleiben. Relationale Daten bilden ein offenes, transparentes Diagramm. Diese beiden Welten scheinen mir völlig unvereinbar zu sein.

ORMs sind jedoch sehr verbreitet und beliebt. Funktioniert die Mehrheit der Webanwendungen mit eher isolierten Entitäten, die gut mit ORM funktionieren, oder warum ist das so? Es scheint mir, dass Sie, wenn Sie ein durchschnittlich komplexes ERD-Modell mithilfe eines ORM-Frameworks implementieren möchten, entweder auf präzisen Code oder auf Leistung verzichten müssen.

Adam Libuša
quelle
1
Jedes Datenbanksystem kann eine geringfügig andere Implementierung haben, um einen Baum oder eine "hierarchische" Datenstruktur zu unterstützen. Beispielsweise verfügt Oracle über START WITH und CONNECT BY und SQL Server über Common Table Expressions (CTEs). Bevor Sie ein ORM auswählen, sollten Sie feststellen, ob es die richtige Unterstützung für diese Art von Datenstrukturen bietet. Einige bieten sehr gute Unterstützung, während andere diese Szenarien möglicherweise nicht abdecken. Diese Frage sollte umformuliert werden: Unterstützt Ecto Baumstrukturen?
Jon Raynor
Da Sie Postgres speziell erwähnt haben, unterstützt es rekursive Abfragen für diese Art von Dingen (obwohl ich es selbst nicht verwendet habe)
Izkata
1
Natürlich sind ORMs ein schlechtes Werkzeug. Es gibt bereits eine Sprache zum ausdrücklichen Ausdrücken von Abfragen in Datenbanken: SQL.
Miles Rout
@Miles Rout In den meisten Fällen wiederholen Sie sich häufig, wenn Sie einfaches SQL anstelle eines ORM verwenden.
Jimmy T.
@ JimmyT. Das ist falsch
Miles Rout

Antworten:

9

Letztendlich ist ein ORM nur eine Abstraktion, die SQL für Sie generiert und die Daten Ihren Objekten zuordnet. Speichern (tm) Sie einige 'Kesselplatte' Code.

Es gibt also nichts, was ORMs als Ganzes per Definition unbedingt schlecht können. Das Problem ist, dass Sie ORMs nicht als Ganzes verwenden, sondern eine bestimmte auswählen und diese verwenden müssen!

Ein einzelner ORM kann eine bestimmte Sache möglicherweise nicht sehr gut machen. Gespeicherte Prozesse, dynamisches SQL, berechnete Felder, komplizierte Verknüpfungen usw. können problematische Bereiche sein.

Ein subtileres Problem besteht darin, dass ein ORM, wenn er versucht, all diese Szenarien generisch zu behandeln, größer und komplizierter wird.

Wenn Sie eine große oder komplizierte Anwendung haben, ist es wahrscheinlich, dass Sie irgendwann auf ein Problem mit dem von Ihnen ausgewählten ORM stoßen. Es ist daher sinnvoll, dies im Voraus zu planen und sicherzustellen, dass Sie das ORM hinter einem Repository verstecken. Auf diese Weise können Sie es gegen eine Alternative austauschen oder bei Bedarf auf handcodiertes SQL zurückgreifen.

Ewan
quelle
1
Es sollte beachtet werden, dass Sie in vielen ORMs (zumindest in jedem, den ich verwendet habe ) Raw-SQL schreiben und ausführen können . Wenn der ORM eine bestimmte Einschränkung nicht gut erfüllt, können Sie daher jederzeit auf natives SQL zurückgreifen und gleichzeitig die SELECT * FROM some_table WHERE x = whateverextrem häufigen "Boilerplate" -Operationen reduzieren . Hierarchische Strukturen werden in einigen ORMs gut und in anderen schrecklich gehandhabt, daher sollte diese Art der Überlegung untersucht werden, bevor entschieden wird, auf ORMs vollständig zu verzichten.
Chris Cirefice
Sie können dies normalerweise tun, aber es funktioniert nicht immer so, wie Sie es möchten! hatte vor kurzem genau dieses Problem mit nHibernate und nullable Field Mapping
Ewan
Ich habe nHibernate noch nie verwendet, aber ich habe einige wie Rails ActiveRecord, OrmLite (Java) und ActiveJdbc (Java) verwendet. Jedes dieser Handles führt Raw SQL anders aus, z. B. ActiveRecord macht es wirklich einfach, und OrmLite hat es wirklich schwierig gemacht. ActiveRecord befindet sich seit Jahren in der Entwicklung, das hat also sicherlich etwas damit zu tun. All diese kleinen Nuancen sind Teil der Machbarkeitstests, aber manchmal vermisst du die kleinen Dinge, die dich später beißen ...
Chris Cirefice
Ja, deshalb sage ich, lege eine Hülle darum. Sie können den Orm weiterhin verwenden, aber Sie sind nicht eingesperrt, wenn Sie in irgendeiner Weise im Stich gelassen werden
Ewan
Sparen (tm) - Ich kicherte ein bisschen darüber.
CorsiKa
7

Sind ORMs einfach ein schlechtes Werkzeug zum Erstellen komplexer DB-Strukturen mit vielen Assoziationen?

Nein. Ruby on Rails verwendet beispielsweise ActiveRecord, das Assoziationen verarbeitet. Im Beispiel hier: /programming/5109893/rails-how-do-self-referential-has-many-models-work wird die baumartige Struktur mit 2 Codezeilen ausgeführt.

Daher würde ich argumentieren, dass es einfacher ist, als zu versuchen, Ihre eigenen SQL-Abfragen zu rollen.

Funktioniert die Mehrheit der Webanwendungen mit eher isolierten Entitäten, die gut mit ORM funktionieren, oder warum ist das so?

Wahrscheinlich nicht, aber das ist nur eine Vermutung. Die ORMs existieren in einem Ökosystem, in dem sie gedeihen, was darauf hindeutet, dass sie verwendet werden. Ich habe ORMs für Systeme mit über 20 zugehörigen Modellen verwendet und fand sie in Ordnung. Ich habe die Objekte nie gezwungen, nur mit Nachrichtenübermittlung isoliert zu werden.

Zusammenfassend lässt sich sagen, dass es bei der Erstellung "komplexer" ERD-Modelle kein Tool gibt, das diese einfach macht. Nur Werkzeuge, mit denen sie funktionieren.

Cmonkey
quelle
Ja - Ich habe Entity Framework für ein Projekt verwendet, bei dem CustomerId (PK) und ParentCustomerId (nullfähige FK, die auf die Kundentabelle verweisen) verwendet wurden, um n Ebenen von Kundenhierarchiebäumen zu erstellen . Hatte hier kein Problem (obwohl viele .Any()
Nullprüfungen
Der Ruhezustand (Java) ist ein weiteres gutes Beispiel für ein ORM, das problemlos mit Bäumen umgehen kann und praktisch keinen zusätzlichen Aufwand erfordert . Die Komplexität von Abfragen ist dem Client verborgen. Eltern und Kinder können faul geladen werden. Die übergeordnete Objekt-ID ist nur eine weitere Spalte in der Datenbank. Eine geordnete Liste von untergeordneten Knoten kann auch transparent unterstützt werden, indem eine Spalte hinzugefügt wird, die einen Listenindex enthält. (Ungeordnete oder geordnete Sammlungsüberlegungen gelten hier nicht nur für Bäume.)
Jason C
Ich kann nicht anders, als das Gefühl zu haben, dass dies eine irreführende Antwort ist. Da ein ORM diesen Fall behandelt, bedeutet dies nicht, dass ORMs im Allgemeinen damit umgehen können. In der Tat zeigt ein kurzer Blick auf Google, dass aktive Datensätze in einigen Versionen Fallstricke und Fehler in Bezug auf selbstreferenzierende github.com/rails-api/active_model_serializers/issues/211 und coderwall.com/p/4d2utg/… aufweisen
Ewan
@Ewan - Ich bin offen dafür, meine Antwort neu zu formulieren, aber ich denke, sie beantwortet die Frage angemessen, wenn ORMs im Allgemeinen schlecht sind. Es ist eine andere Frage, ob alle ORMs diesen Fall behandeln können oder ob sie die beste Lösung sind. Das Vorhandensein eines weniger geeigneten ORM-Tools oder eines Fehlers in einer Version ändert nichts an der Generalisierung. Ich weiß auch, dass ich auch Fehler in meinem SQL hatte.
Cmonkey
5

Wie in mindestens einer anderen Antwort hier erwähnt, sind nicht alle ORMs gleich. Einige ORMs machen sehr wichtige Annahmen darüber, wie die Datenbank strukturiert sein sollte. Das Werkzeug sollte eine gewisse Unterstützung für das Verlassen dieses Modells bieten. Je mehr Sie sich jedoch von diesem Modell entfernen, desto weniger Wert hat das ORM. Wenn Sie mit einem dominanteren ORM-Tool arbeiten, haben Sie eine viel bessere Erfahrung, wenn Sie die Datenbank anhand ihrer impliziten Annahmen entwerfen.

Ich habe nie wirklich verstanden, warum ORMs von vielen Entwicklern und Architekten als wesentlich angesehen werden. Dies kann auf die Tatsache zurückzuführen sein, dass ich fast nie eine Green-Field-Datenbank hatte, mit der ich arbeiten konnte, und dass der Zeit- und Arbeitsaufwand für die Durchführung der ORM-Zuordnung weitaus mehr Arbeit war als das Schreiben von SQL. Entweder war das Mapping einfach (und auch das SQL) oder es war kompliziert und ich brauchte sowieso SQL (oder ähnliches). Die in ORM enthaltene Transaktionsunterstützung war meiner Erfahrung nach eher eine Quelle von Fehlern und Problemen als eine Hilfe.

Ihr Kilometerstand kann variieren, aber ich bin zu der Überzeugung gelangt, dass es besser ist, die Datenbankpersistenz als einen speziellen Fall der Datenserialisierung zu betrachten. Und genau wie ich denke, dass es keinen Sinn macht zu glauben, dass Sie ein Objekt über das Kabel "senden" können, halte ich es nicht für sinnvoll, daran zu denken, Objekte in eine Datenbank zu schreiben. Ich denke sogar, dass es völlig gültig ist, mehrere Objektdarstellungen derselben Daten für unterschiedliche Anforderungen zu haben. Das Zuordnen von Objekten zu Tabellen und umgekehrt ist zu einem Selbstzweck geworden, im Gegensatz zu einer Lösung eines Problems. Ich bin nicht davon überzeugt, dass die meisten Leute, die diese Tools verwenden, sogar einen klaren Grund haben, dies zu tun. Es ist ein Standard geworden.

JimmyJames
quelle
1
totes stimmen zu, wenn Sie sich damit abfinden, das SQL auszutippen und zuzuordnen, dauert es auf lange Sicht selten länger und Sie haben die totale Kontrolle
Ewan
@Ewan Um fair zu sein, ich denke, es braucht ein bisschen Erfahrung, um zu wissen, wie man die richtigen Abstraktionen zwischen der Logik und der DB erstellt. ORMs können Entwicklern helfen, schnell zu etwas zu gelangen, das funktioniert. Es ist die Idee, dass Objekte in Tabellen übersetzt werden können und umgekehrt, wo ich denke, dass es Probleme gibt. Dies gilt für eine Teilmenge von Datenmodellen und Objektmodellen, jedoch nicht allgemein.
JimmyJames
1
@JimmyJames Es ist wahr, wenn Sie nur sehr einfache CRUD-Operationen pro Tabelle benötigen. Darüber hinaus ist ein Nicht-Mikro-ORM ein Fluch. (Und ich persönlich finde die Idee, ein Objekt für jeden Satz von Spalten zu erstellen, die für ein Mikro-ORM zurückkommen, ärgerlich, obwohl es in einer statisch typisierten Sprache möglicherweise weniger ärgerlich ist.)
jpmc26
1
@ jpmc26 Ich möchte den statischen und dynamischen Sumpf umgehen, aber ich denke, Sie heben die Art von Dingen hervor, über die ich spreche. Wenn ich nur einige Daten abrufen, minimal transformieren und als JSON zurückgeben möchte, muss ich sie nicht wirklich Objekten zuordnen, um dies zu erreichen. Das Objekt hat keine echte Funktionalität. Es fungiert als Karte, auf der Daten momentan gespeichert werden. Aber ich habe ORMs gesehen, mit denen solche Probleme gelöst wurden. Oft besteht die Antwort darin, die Klassen für diese Objekte zu generieren, aber ich denke, das zeigt nur, wie unnötig sie sind.
JimmyJames
Irgendwie habe ich das ausgelassen, was ich ursprünglich sagen wollte: Mit einer brandneuen Datenbank, die Sie entwickeln, ist die Situation nicht besser. Dies hängt nur von der Art der Abfragen ab, die Sie schreiben müssen. Für eine sehr einfache CRUD pro Tabelle kann dies etwas Zeit sparen. Wenn Sie jedoch Abfragen haben, die Daten aus verschiedenen Tabellen mischen oder abgleichen, oder komplexe Abfragen (komplexe Gruppierung, CTEs, Unterabfragen), ist alles, was nicht mikro ist, automatisch viel schwieriger als es wert ist. Selbst wenn Sie zu Beginn mit sehr einfachem CRUD davonkommen können, wetten Sie, dass Erfolg nicht zu größerer Komplexität führt.
jpmc26