burli hat geschrieben:Ob ein ORM in jedem Fall vorzuziehen ist weiß ich nicht. Ich sehe noch nicht den ultimativen Vorteil eines ORM. Für meinen Geschmack wird das zu stark abstrahiert und man verliert die Kontrolle über die Datenbank. Vor allem habe ich Bedenken was die Performance und die Optimierungsmöglichkeiten angeht. Ich weiß nicht ob und wie es möglich ist zb Trigger oder Stored Procedures zu verwenden.
Hallo!
Ich bin voll burlis Meinung. Ein gutes Datenbanksystem bietet mehr als nur das einfache Abspeichern und Wiederfinden von Daten.
Ein gutes Datenbanksystem kann man so verwenden, dass so wenig Daten wie nötig über das langsame Netzwerk geschickt werden. Und das ist bei verteilten Anwendungen das Um und Auf.
Weiters bietet ein Datenbanksystem wie PostgreSQL eine Benutzerverwaltung mit Rechtevergabe, Gruppen, Benutzern usw. So kann man als Anwendungsentwickler auf ein bereits fertiges Authentifizierungssystem und Berechtigungssystem zugreifen.
Durch Beziehungen zwischen den Daten/Tabellen, werden Datenleichen vermieden. Durch gezieltes Indizieren der Daten werden Suchanfragen beschleunigt. OK, das können die meisten ORMs auch.
Aber wo ORMs total auf die Schnauze fallen: Das Erstellen von temporären Tabellen, Befüllen dieser Tabellen mit gefilterten Daten, nachträglichem Indizieren dieser Tabellen und abschließendem Abfragen der gewünschten Daten aus diesen vorgefilterten Tabellen. Das ist nämlich etwas, was auch bei meinen (großen) Datenbankanwendungen extreme Geschwindigkeitszuwächse bringt. Statt einer Abfragelaufzeit von zwei Stunden, sind so Laufzeiten von wenigen Minuten herauszuholen. Besonders bei großen Datenbanken mit z.B. Verkaufsdaten, Rechnungen, Lieferscheinen, Artikelbewegungsdaten usw.
Ich sage ja nicht, dass ORMs eine große Erleichterung sein können. Kleine und mittlere (subjektiv gesehen) Anwendungen lassen sich damit sicher einfach erstellen. Überhaupt für jemanden, der mit SQL noch nichts zu tun hatte, dürfte das eine Erleichterung sein. Aber wenn jemand die gleiche Energie in das Lernen von SQL steckt, die er/sie für das Erlernen des ORMs braucht, dann kommt man, meines Erachtens, mit SQL weiter. Denn mit SQL lassen sich kleine, mittlere und auch große Anwendungen schreiben. Anwendungen, die nicht nur lokal oder auf einem Webserver laufen, sondern auch verteilte Anwendungen, die auf eine gemeinsame globale Datenbank zugreifen müssen. Anwendungen, die die Arbeitsdaten in einer lokalen Datenbank cachen und die aktuellsten Daten in einer zentralen Datenbank verwalten.
Unabhängig davon was ich bis jetzt geschildert habe, gibt es ja noch mehr, was einem eine Datenbank bietet. Z.B. kann man Regeln definieren um die Daten zu prüfen, bevor diese auf die Festplatte geschrieben werden. So kann mit einfachen Datenbankregeln geprüft werden, ob z.B. ein gewisser unrealistischer Betrag überschritten wird, oder ob das Geburtsdatum eines neugeborenen Babys auch wirklich realistisch ist. So etwas ist eine praktische Prüfung auf Datenebene. Z.B. wird auf diese Weise global vor Fehleingaben gewarnt. Wenn man nicht nur selbst auf die Daten zugreifen muss, wenn mehrere Entwickler und/oder mehrere verschiedene Clientprogramme im Spiel sind, dann ist so eine zentrale Plausibilitätsprüfung der Daten Gold wert.
Manche werden jetzt einwenden, dass man ja eine Middleware schreiben kann, die einzig auf die Datenbank zugreifen darf. Und alle Clients müssen über diese Middleware gehen. Aber in der Praxis ist das oft nicht oder nur mit erhöhtem Programmieraufwand machbar. Was ist, z.B. wenn ein Manager bestimmte Auswertungen braucht? Dann greift man normalerweise mit einem Werkzeug wie Crystal Reports, Report Manager oder BIRT direkt auf die Datenbank zu. Oder zum Aufbauen von Datawarehouse-Anwendungen (sammeln von Daten zur vereinfachten zusammengefassten Auswertung). Für so etwas gibt es Anwendungen, die direkt auf die Datenbanken zugreifen. Man kann auch nicht ausschließen, dass irgendwann mal jemand direkt in die Datenbank schreibt oder dort Änderungen durchführt, die das ganze System durcheinander bringen können. Das kann mit Access, OpenOffice.org, oder irgend einem anderen Tool ohne Weiteres gemacht werden.
Aber um wieder auf den Punkt "Geschwindigkeit" zurück zu kommen. Es gibt ja noch mehr Dinge, die man ausnutzen kann um Datenbankanwendungen schneller zu machen. Z.B. kann man Sichten (vorgefertigte Abfragen) definieren. Diese sind dann in der Datenbank bereits vorkompiliert und müssen nicht bei jeder Anfrage neu aufbereitet werden. Manche Datenbanken bieten es sogar an, dass diese Sichten indiziert werden können. Dann hat man schon vorkompilierte Abfragen mit Indizes, die die Abfragen schneller machen.
Einen Geschwindigkeitsvorteil konnte ich z.B. beim Einsatz von "Gespeicherten Prozeduren/Funktionen" feststellen. Diese stellen, wie die Sichten, eine vorkompilierte Abfrage dar. Der Unterschied ist, dass man an diese Prozeduren auch Parameter übergeben kann und dass die Sprache in der solche Prozeduren/Funktionen erstellt werden können, meist mächtiger als das normale SQL ist. Wenn es in enormen Maße auf Geschwindigkeit ankommt, dann kann man unter PostgreSQL solche Funktionen sogar in C schreiben. Wenn die Geschwindigkeit nicht so wichtig ist, dann können solche Datenbankfunktionen sogar mit Python, Java oder TCL geschrieben werden. Über die Geschwindigkeitsunterschiede kann ich jetzt nur mutmaßen, da ich sie nie miteinander verglichen habe.
Trigger: Damit kann man Anweisungen ausführen lassen, wenn Daten in eine Tabelle geschrieben, aus dieser Tabelle gelöscht, oder wenn die Daten einer Tabelle verändert werden. Natürlich könnte man das auch in einer Middleware machen. Aber wenn man diese Aufgabe an die Datenbank bindet, dann ist die Datenintegrität eine Spur sicherer. Denn die Datenbank kann nicht so einfach übergangen werden. Die Middleware schon.
Für was könnte so ein Trigger gut sein? Hier ein Beispiel aus meiner aktuellen Anwendung: Eine Bestellung besteht aus vielen Bestelldetails (Artikel). Es werden einzelne Artikel aus mehreren Bestellungen zu Lieferscheinen zusammengefasst. Und erst dann, wenn alle Bestelldetails auf irgendeinem Lieferschein sind, gilt die Bestellung als "ausgeliefert". Trigger kümmern sich beim Erstellen der Lieferscheine darum, dass die zugehörigen Bestellungen entsprechend markiert werden. Diese Markierung ist wichtig, um spätere Auswertungen zu beschleunigen. Löscht/storniert man eine Lieferung, dann wird die Markierung für die betreffenden Bestellungen wieder zurückgesetzt. Da die Datenbank sich darum kümmert, kann kein Programm diesen Mechanismus unabsichtlich umgehen. Die Datenintegrität bleibt sichergestellt.
Ich könnte noch viel mehr darüber schreiben, welche Aufgaben eine gute Datenbank einem Programmierer abnehmen kann, die von einem ORM schlicht nicht durchgereicht werden können. Aber ich muss mich jetzt ums Brötchenverdienen kümmern und ein wenig an der Datenbankstruktur eines firmeninternen Bestellwesens für eine Großkonditorei feilen.
Ich glaube, dass man nicht einfach so behaupten sollte, dass man mit Python kein SQL mehr braucht. Es kommt immer auf die Anwendung an. Wenn einem eine Datenbank Arbeit abnehmen kann, dann sollte man
mit dieser Datenbank arbeiten und nicht eine Abstraktionsschicht dazwischen schieben. Ich finde, dass ORMs vielleicht interessant sind, für reine Desktopanwendungen oder Internetanwendungen, die auf einem Webserver laufen. Da ist auch das Argument, dass man damit ohne Umstellung mit mehren Datenbanksystemen arbeiten kann, begründet. Aber wenn man typische Client-Server-Anwendungen schreibt, dann sollte man sich gut überlegen, ob man mit einem ORM die Funktionen der Datenbank aussperren möchte, die das Programmieren von Client-Server-Anwendungen so viel einfacher machen. Datenbanksysteme wie z.B. PostgreSQL sind hauptsächlich dafür geschaffen, um mehreren (auch verschiedenen) Clientsystemen Zugriff auf einen zentralen Datenbestand zu bieten. Und genau dafür bieten sie Funktionen wie Benutzerverwaltung, Authentifizierung, Berechtigungsverwaltung, Transaktionen, Row-Locking, Page-Locking, Table-Locking, und noch viel mehr.
lg
Gerold
PS: Entschuldigt, dass ich so viel geschrieben habe.