schlaue DB + dummer server vs. dumme DB + schlauer server
-
Mich würde eure Meinung zu zwei "Modellen" bei Client/Server Applikationen interessieren.
(Bzw. einfach zu einer mMn. wichtigen Design-Entscheidung)Dazu muss ich nochmal genauer erklären was ich meine - der Titel triffts nicht ganz genau (hab aber keine bessere kurze Formulierung gefunden).
Variante A:
Die Datenbank ist der "Chef". Die Server-Applikation ist "doof" und macht nicht viel mehr als Werte in die DB zu stopfen/auszulesen. Plus ggf. den einen oder anderen Plausibilitätscheck oder Prüfen von Constraints die in der DB nicht oder nur mit nicht vertretbarem Aufwand modelliert werden könnten.
Der Knackpunkt bei der Variante ist, dass das System so aufgebaut ist, dass man im Prinzip auch zwei oder drei Server-Applikationen gleichzeitig auf der selben DB laufen lassen könnte.
Sämtliche Daten werden entweder von der Server-Applikation bei jeder Anfrage immer neu aus der DB geladen, bzw. wenn die Server-Applikation Daten cached setzt sie bei jedem Client-Request eine Query ab um zu checken ob die Daten eh noch "synchron" mit der DB sind.Variante B:
Die Server-Applikation ist Chef. Die DB wird quasi nur als "besseres File" verwendet um die Daten sicher abzuspeichern. Die Server-Applikation hält Daten die sie für sinnvoll erachtet im Speicher, und geht davon aus dass keine Änderungen direkt in der DB gemacht werden. Änderungen an Daten/Entities sind also nur über "Services" erlaubt die in die Server-Applikation integriert sind.
Vorteile von A:
* Man kann jederzeit Änderungen direkt in der DB vornehmen (mittels ad hoc Queries, Access, ...)
* Man kann verschiedene Server-Applikationen gleichzeitig laufen lassen (verschiedene Versionen, evtl. eine Webseite die direkt auf die DB zugreift etc.)Nachteile von A:
* Man wird u.U. gezwungen ein etwas komplizierteres Datenmodell zu verwenden, um die nötigen "ist mein Wert noch aktuell" Checks des Servers performant durchführen zu können
* Man braucht u.U. stärkere Hardware (speziell für die DB), da viele "unnötige" Abfragen auf die DB gemacht werden müssenVorteile von B:
...?Nachteile von B:
* Jegliche Änderung an Daten/Entities wird zum Problem (Server stoppen oder dem Server beibringen die Änderung selbst zu machen)Was mich jetzt interessieren würde:
* Fallen euch noch weiter Vor-/Nachteile der beiden Varianten ein?
* Welches Variante habt ihr bisher in Projekten verwendet, und was für Erfahrungen habt ihr damit gemacht?
* Welches Variante würdet ihr für zukünftige Projekte einsetzen?
-
Arrrr...
Ich hab mich vertan - wollte das eigentlich in Rund um die Programmierung schreiben. Bitte 1x verschieben wenn möglich.
-
1.) Was ist das Ziel? Kommunikationsaufwand senken oder Performance?
2.) Wie wartungsvertraeglich sind beide Varianten? (Da verliert wohl Variante 2)
-
hustbaer schrieb:
Mich würde eure Meinung zu zwei "Modellen" bei Client/Server Applikationen interessieren.
Du solltest dir vorher erst einmal über die Rahmenbedingungen klar werden, diese können ganz massiv die Bewertung beider Varianten beeinflussen. Nur so nebenbei: Ich kenne beide Extreme aus der Praxis und mir gefallen beide aus mehreren Gründen nicht. Ich kenne Argumente für und wider beider Ansätze und ziehe persönlich eher einen Mittelweg vor, der aber auch einen Servicelayer beinhaltet, wenn mehrere Anwendungen beteiligt sind.
Beispiel: Wie sehr kann das Datenbanksystem festgelegt werden?
Die Frage kommt nicht von ungefair. Wenn ich nur die Fälle, die ich selbst bei einem Produkt mitbekommen habe in Relation setze, gehe ich davon aus das wir in der letzten Firma weit mehr potentielle Kunden über die Festlegung auf ein Datenbanksystem als auf ein Betriebssystem verloren haben. Mag sein das inzwischen andere Systeme entscheidend waren, früher waren die beiden meist angeforderten Systeme entweder MS SQL Server oder Oracle. Es gab nicht wenige Interessenten die sich hier genau auf ein System festgelegt hatten, und kein anderes zuließen.
Wenn man sich auf ein DB-System festlegen kann, mag eine Fixierung auf die Datenbank durchaus okay sein. Aber ansonsten muss man mit teilweise massiven Mehraufwand rechnen. Was ein Punkt gegen A sein kann.
Es gibt noch viele weitere Faktoren die tatsächlich für und wider A und B sprechen. Ich ziehe nach meiner Erfahrung C vor (Liegt aber vielleicht auch daran das ich in der Regel an langjährigen Produkten mit entwickle, die über keine riesigen Teams verfügen).
Eine Datenbank die zwar viele Constrains enthält, und auch wo sinnvoll einfache Trigger und CRUD-STPs enthält, aber sich gleichzeitig noch die DB-Abhängigkeit in Grenzen hält. Der Pflegeaufwand um ggf. mehrere DB-Systeme unterstützen zu können sollte sich noch in Grenzen halten. Und ja, ich präferiere über einer Datenbank noch eine mindestens flache Serviceschnittstelle, die direkte DB-Änderungen kapselt.
-
Also zu euren Fragen...
Einerseits geht es mir allgemein darum dass mich Meinungen zu dem Thema interessieren würden.
Ich habe bisher immer nur Variante A gemacht (siehe nächster Beitrag, damit meine ich nicht dass die ganze Business-Logik in SQL gemacht wird). Das grösste Problem das ich dabei hatte, ist, dass das Datenmodell vorab nicht gut genug geplant wurde. Dadurch hatten wir dann bald ziemlich miese Performance. Die dann nötige Änderung war manchmal recht aufwendig.
Nun hab' ich mir überlegt bei meinem nächsten Projekt Variante B zu bauen. Allerdings bin ich da sehr skeptisch. Andrerseits weiss ich dass ich damit massiv Performance sparen könnte...
Zu den Rahmenbedingungen...
Es geht um "in house" Software. Datenbank ist fix SQL Server und OS ist fix Windows - was anderes verwenden wir nicht. Sich da festzulegen ist also kein Thema - flexibilität wird hier nicht benötigt.
-
Und, speziell @asc, ich hab' mich da vielleicht nicht so gut ausgedrückt...
Ich meine bei Variante A nicht, dass man unbedingt haufenweise Business-Logik direkt in als Stored-Procedure in der DB implementiert.Die wichtigste Frage für mich ist: ist es OK ein System zu schaffen, bei dem Änderungen nicht direkt in der DB gemacht werden dürfen, sondern über eine Server-Applikation/Service-Schnittstelle/... gemacht werden müssen?
Das ermöglicht nämlich einerseits sehr effizientes "sorgloses" Caching in der Server-Applikation/Service-Schnittstelle/..., was ja eine gute Sache ist.
Andrerseits finde ich es nicht gut, wenn man die Server-Applikation/Service-Schnittstelle/... anhalten muss, nur weil man mal mit einer ad hoc Query ein paar Werte in der DB anpassen möchte.Und da gibt es mMn. dann auch keinen Mittelweg mehr: entweder Änderungen direkt in der DB sind während die Server-Applikation läuft erlaubt (A), oder eben nicht erlaubt (B).
(Man kann natürlich direkte Änderungen an bestimmten Entities/Werten erlauben, und an anderen nicht. Das wird dann aber schnell unübersichtlich.)
-
Zum einen kann die Datenbank auch deine eigene Server-Applikation benachrichtigen. Wir machen das z.B. Wir Cachen Tabellen die ständig im Zugriff sind. Diese werden nur sehr selten beschrieben, aber sehr, sehr häufig gelesen. Auf diesen Tabellen haben wir Trigger, die unsere Server-Applikation über Änderungen an den Tabellen informiert, damit diese den Cache aktualisieren kann.
Zum anderen wüsste ich nicht, warum man einen Server für eine Ad-Hoc-Abfrage anhalten müsste? Ich wüsste keine Datenbank, die mit mehreren gleichzeitigen Verbindungen ein Problem hätte?!? Auf unserer Datenbank nudeln z.B. auch noch andere Anwendungen rum (Die ganzen schönen bunten Diagramme werden von Fremd-Anwendungen erstellt). Andererseits kann sich der Anwender aber auch Exporte über eine GUI zusammenklicken und die Daten z.B. nach Excel exportieren, um dort weiterzuverarbeiten. Wobei das aber immer seltener genutzt wird, die meisten greifen direkt über ODBC drauf zu.
Wir haben auch Tabellen, die nur direkt von unserem Server beschrieben werden können (Trigger der über eine Prüfsumme bei Änderungen Fehler wirft), weil es bei bestimmten Daten sehr strenge Vorschriften gibt, dass diese Daten nicht mehr verändert werden dürfen, wenn sie Ausgedruckt und dem Kunden mitgegeben wurden.
Allerdings haben auch wir das Problem, dass wir uns mittlerweile zu sehr auf eine Datenbank eingeschossen haben, und halt viele Features dieser Datenbank nutzen, die andere Datenbanken nicht bieten. Dadurch haben wir auch schon recht häufig Absagen von Kunden bekommen, rein auf Grund der Datenbank die wir verwenden...
-
hustbaer schrieb:
Die wichtigste Frage für mich ist: ist es OK ein System zu schaffen, bei dem Änderungen nicht direkt in der DB gemacht werden dürfen, sondern über eine Server-Applikation/Service-Schnittstelle/... gemacht werden müssen?
Halte ich für einen Ansatz der durchaus möglich und gebräuchlich ist. In sehr kleinen Firmen, wie der in der ich gerade arbeite, wird es wohl auch zwingend in eine solche Richtung gehen (Wir können nicht n verschiedene Systeme mit m verschiedenen Sprachen gut betreuen, zudem hat mein Chef ohnehin schon Probleme mit Logik die er nicht im Code zentral nachlesen kann - auch wenn er inzwischen damit leben kann das ich in SQL einiges löse wofür er früher viel Code geschrieben hat).
hustbaer schrieb:
...Andrerseits finde ich es nicht gut, wenn man die Server-Applikation/Service-Schnittstelle/... anhalten muss, nur weil man mal mit einer ad hoc Query ein paar Werte in der DB anpassen möchte.
Warum sollte man die Server-Anwendung dabei Anhalten müssen? Was sein könnte wäre das man den Cache informieren muss, das dieser neu zu laden ist.
hustbaer schrieb:
Und da gibt es mMn. dann auch keinen Mittelweg mehr: entweder Änderungen direkt in der DB sind während die Server-Applikation läuft erlaubt (A), oder eben nicht erlaubt (B).
Ich war noch nie ein Freund davon, wenn zu Viele direkt auf einer Datenbank arbeiten, ich kenne die Probleme schon von unseren Kunden wo einige es geschafft haben die Daten zu zerschießen, weil sie ohne Rücksprache meinten Importe usw. schreiben zu müssen - aber ohne die DB-Struktur verstanden zu haben.
hustbaer schrieb:
(Man kann natürlich direkte Änderungen an bestimmten Entities/Werten erlauben, und an anderen nicht. Das wird dann aber schnell unübersichtlich.)
Ich halte das nicht für so unübersichtlich. Mein persönlicher Favorit ist hierbei inzwischen:
Vom Grundsatz her ist die Datenbank erst einmal für Externe gesperrt, mit folgenden Ausnahmen:
a) Es werden rein lesende Views bereit gestellt, die Auswertungen ermöglichen, ohne aber alle interne Daten offen zu legen.
b) Es werden einzelne Import- und Exporttabellen (oder entsprechende STPs) für einfache Stammdaten Im-/Exporte angeboten.
c) Für komplexere Abläufe wird die Serviceschnittstelle, die wir selbst auch nutzen zur Verfügung gestellt. Gefahr hierbei ist aber das diese an einigen Stellen "instabiler" ist, als die beiden anderen Varianten.
-
BadWolf schrieb:
Dadurch haben wir auch schon recht häufig Absagen von Kunden bekommen, rein auf Grund der Datenbank die wir verwenden...
Mich würde mal interessieren was für Datenbanken bei euch die wichtigsten Kandidaten waren (in meiner aktuellen Firma ist dieses Problem wesentlich kleiner, da unsere Kunden zum Großen Teil in einem Bereich liegen, bei dem der Microsoft und der SQL Server recht dominant sind).
Wobei auch bei uns vermutlich kompromisse geschlossen werden: Durch die Begrenzten Kapazitäten (sehr kleine Firma) beginnen wir mit einer DB (hier SQL Server), versuchen aber im Funktionsumfang nur Sachen zu nutzen, bei dem ich relativ sicher sein kann, das zumindest auch Oracle und Posgresql diese abdecken können (Damit begrenzt man zwar auch die Auswahl, lässt den Kunden aber Gleichzeitig noch etwas Spielraum).
Durch ein paar andere Problematiken bin ich inzwischen sogar kurz davor mich von Triggern und STPs zu verabschieden, und doch alles über Programmlogik bzw. Import-/Exporttabellen lösen zu wollen. Da der Aufwand für die Doppelpflege recht hoch wird.
z.B. wollen wir eine "echte" und vollständige Historie. Nun habe ich die Wahl die über Trigger oder die Programmlogik zu machen, nach und nach scheint letzteres aber die bessere Option zu werden. Zumal ich mich nicht auch noch intensiv in T-SQL einarbeiten kann, wenn ich selbst noch genügend andere Baustellen pflegen (und noch diverse Einarbeitungen erledigen) muss. Wir haben hier keinen DB-Administrator, und ich bin der einzige der an einer Migration auf eine große DB + .Net arbeitet und dort auch noch ständig (teilweise Monatelang) unterbrochen wird... Sprich, es wird nur klappen wenn ich ein paar Stellen "vereinfache".
-
BadWolf schrieb:
Zum einen kann die Datenbank auch deine eigene Server-Applikation benachrichtigen. Wir machen das z.B. Wir Cachen Tabellen die ständig im Zugriff sind. Diese werden nur sehr selten beschrieben, aber sehr, sehr häufig gelesen. Auf diesen Tabellen haben wir Trigger, die unsere Server-Applikation über Änderungen an den Tabellen informiert, damit diese den Cache aktualisieren kann.
In vielen Fällen wird das gut funktionieren.
Es gibt aber Fälle wo es ein Problem macht, wenn der Server davon ausgeht dass er der einzige ist der irgendwas ändert.
Es reicht schon das klassische "zwei Konten" Beispiel.
Normalerweise, also wenn man von mehreren "Schreibern" ausgeht, muss man hier eine Transaktion machen, in dieser Transaktion dann beide Zeilen lesen, die gelesenen Werte überprüfen und in der selben Transaktion die beiden Zeilen wieder schreiben.
Dann ist, passender Isolation-Level vorausgesetzt, garantiert dass sich mehrere Schreiber nicht in die Quere kommen. Bzw. ein Schreiber einfach kontrolliert abbricht, z.B. wenn auf dem "Absender" Konto nicht mehr genügend drauf ist.Wenn man nun festlegt dass der Application-Server der einzige ist der Konten updaten darf, dann spart man sich das, und schreibt einfach die neuen Werte raus ohne vorher irgendwas aus der DB zu lesen. Wenn jetzt jmd. "von ausserhalb" die Datenbank ändert, dann kann es, ungünstiges Timing vorausgesetzt, passieren dass der Server Mist schreibt, weil seine gecachten Ausgangsdaten nicht mehr aktuell waren. Dadurch kann dann entweder die externe Änderung einfach rückgängig gemacht werden (blöd aber nicht katastrophal), oder, wenn z.B. nur eines der beiden Konten gecached war, das andere aber nicht, sogar ein inkonsistenter Zustand hergestellt werden (Summe über alle Konten nicht mehr Null, sehr sehr blöd).
In diesem einfachen Beispiel spart man sich freilich nicht viel, denn zwei Zeilen zu lesen die in der selben Transaktion wieder beschrieben werden ist nicht wirklich teuer. Es gibt aber durchaus ähnliche Fälle wo die Einsparung signifikant wäre.
Zum anderen wüsste ich nicht, warum man einen Server für eine Ad-Hoc-Abfrage anhalten müsste? Ich wüsste keine Datenbank, die mit mehreren gleichzeitigen Verbindungen ein Problem hätte?!?
Ich meinte Queries die Daten modifizieren (INSERT/UPDATE/DELETE). Hätte ich vielleicht nochmal klarer dazuschreiben sollen.
Und wenn man im Application-Server davon ausgeht dass nur der Application-Server alleine schreiben darf, dann kann das wie gesagt ganz schnell zu einem Problem führen. Nicht was die low-level Konsistenz der Datenbank angeht (Tabellenstrukturen/Indexe etc.), sondern was die high-level (Business-Logik) Constraints/Invarianten/... angeht.
-
Mich würde eure Meinung zu zwei "Modellen" bei Client/Server Applikationen interessieren.
(Bzw. einfach zu einer mMn. wichtigen Design-Entscheidung)Wenn das so einfach und pauschal zu sagen waer, dann waeren aber auch viele Beratungsfirmen brotlos ....
Glaub am haeufigsten in der Praxis wird Variante B2 nach deinem Muster propagiert, also der Klassische Doof - Intelligent - Doof Ansatz, also doofer Strore, Intelligente Zwischenschicht aka Middleware, doofer Darstellungsschicht, aka GUI Software / Browser.
Problem ist aber der Durchsatz von der Middleware. Wenn man da an grenzen kommt, und per definition kann man da nur vertikal skalieren ... was ganz schnell an Grenzen kommen kann. DIe verfügbarkeit ist sicher auch nicht unkritisch.
Für kleinere Anwendungsfälle durchaus tragbar, für hochverfügbarkeits- und Hochleistungs-Anwendungen sich nicht gangbar.Gescheit horizontal skalieren kannst meist dann auch nur, wenn die Anbindung mehrerer App-Server (middelware) auf die DB nicht ueber eine Leitung begrenzt wird ... dann kommst schnell zu dem fall das Daten auf mehrere Server aufteilst und dann brauchst auch schon eine gewisse Intelligenz auf den servern ... Bzw da gibts auch Lösungen, womit sich RDBMS als Komplettlösung abheben wollen.
Da gibts noch ne Menge weiterer Ansaetze ....
z.b. braucht man oft keine Transaktionssicherheit ueber alle Ebenen, dann bietet es sich an, die Datenbanken nach Inhalt zutrennen ...Ich würd den konkreten Anwendungsfall mit einbeziehen bei der Entscheidung
Oftmals entscheidet dann auch die Finanzabteilung, suendhaft teurer DB Server inkl. Software vs. Eigenentwicklung.
Ich hab auch schon Projecte mit MS-Access + VB und PowerBuilder und sowas umsetzen muessen. Manchmal sind "Niedrige initiale ENtwicklungskosten" halt schon nen totschlag-Argument.
Und mit ner "Intelligenten DB" kann man oft viel an ENtwecklung anderswo sparen .. erstmalCiao ...
-
hustbaer schrieb:
Ich habe bisher immer nur Variante A gemacht (siehe nächster Beitrag, damit meine ich nicht dass die ganze Business-Logik in SQL gemacht wird). Das grösste Problem das ich dabei hatte, ist, dass das Datenmodell vorab nicht gut genug geplant wurde. Dadurch hatten wir dann bald ziemlich miese Performance. Die dann nötige Änderung war manchmal recht aufwendig.
Kannst du denn dann die Server-Applikation so designen, dass sie nie Performanceprobleme hat?
Wenn ja, wie machst du das?Warum kann/konnte das Datenmodell nicht angepasst werden, so dass die Performance nicht mies wird?
Kannst du vielleicht ein konkretes Beispiel nennen?
Ich würde immer zu Variante A tendieren, ich kann mir gerade nicht vorstellen, dass man das Datenmodell nicht immer performant nachziehen kann.
Natürlich kann irgendwann die große Datenmenge und Aggregation von Daten das System auslasten und für andere Verbindungen ausbremsen.
Für sowas würde ich einen Datawarehouseansatz vorschlagen: insert/update/delete immer auf der Hauptdatenbank, selects dafür auf beliebig vielen Kopien die durch datenbanksystemeigene Mechanismen aktuell gehalten werden.j
-
@jenz
Nein, garantieren kann man natürlich nie etwas.
Aber Änderungen werden einfacher, wenn nur ein Programm existiert welches direkt auf die DB zugreift.
Und ein Datenmodell, das nicht darauf ausgelegt ist dass das Serverprogramm sehr schnell abfragen kann, ob gecachte Daten noch aktuell sind, wird evtl. einfacher als eines, wo das doch möglich sein muss.Aber je länger ich darüber nachdenke, desto eher denke ich Variante A ist auf jeden Fall besser.