Entwickler-Ecke

Datenbanken - Konzeptfrage: Datenhaltung in DB, auf Ereignisse reagieren


Narses - Sa 10.01.15 20:18
Titel: Konzeptfrage: Datenhaltung in DB, auf Ereignisse reagieren
Moin!

Tja, beim Thread-Titel hab ich mir schon einen abgebrochen, mit Suchenworten für Tante Google ist´s gleich ganz vorbei... :? ich glänze mal wieder mit meinem mangelhaften Datenbank-Konzept-Wissen :( und bin auf eure Hilfe angewiesen... :flehan:

Ich habe eine MySQL-DB, auf die greift ein Webserver-Prozess per PHP und eine Delphi-Anwendung per mysql.dll zu. Der Webserver-Prozess verarbeitet HTTP-Requests und dabei entstehen "Ereignisse" (ein Feld ändert seinen Wert), darauf soll die Delphi-Anwendung reagieren. Aber möglichst ereignisorientiert, nicht per Pollen der Tabellen. :shock: Wie macht man sowas?! :nixweiss: Bitte einen Denkanstoß oder Konzeptvorschlag... :eyes:

cu
Narses


Martok - Sa 10.01.15 20:55

Events aus einem Datengrab? Hmmm :gruebel:

Das Einzige was mir da einfällt wäre eine gesonderte Event-Liste (=Tabelle), in der alle Events abgelegt werden, dann muss die Delphi-Anwendung nur diese pollen und kann abgearbeitete Einträge rauswerfen. So machen das eigentlich alle die asynchrone Jobs brauchen (Sidekiq oder sowas).

Die Events könnte man dort per ON UPDATE-Trigger auf den Datentabellen einfügen lassen (oder das gleich aus dem PHP-Skript raus machen), je nachdem wie viel Logik in der DB wohnen darf...


Narses - Sa 10.01.15 21:43

Moin!

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Events aus einem Datengrab?
Wieso Datengrab? :gruebel: Oder hab ich den Witz nicht verstanden? :lol:

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
eine gesonderte Event-Liste (=Tabelle), in der alle Events abgelegt werden, dann muss die Delphi-Anwendung nur diese pollen und kann abgearbeitete Einträge rauswerfen.
Ich möchte möglichst zeitlich nahe an den Ereignissen sein, aber möglichst wenig pollen. :? Hört sich nach entgegengesetzen Enden an, oder... ? :nixweiss: :eyes:

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Die Events könnte man dort per ON UPDATE-Trigger auf den Datentabellen einfügen lassen
Jup.

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
(oder das gleich aus dem PHP-Skript raus machen)
Ich könnte auch dem Delphi-Server per UDP "bescheid" sagen. Dann holt der sich den Datensatz ran und fängt mit den Aktionen an. :idea: Aber sowas klingt irgendwie ... krude? :hair: Ich hatte gehofft, es gibt da irgend eine smarte Möglichkeit in einem RDBMS, wie man sowas löst und ich kenn sie nur schlicht nicht... :lol:

cu
Narses


mandras - Sa 10.01.15 21:52

Wenn Du Zugriff auf die PHP-Skripte hast (diese also selber ändern kannst) wäre m.E. nach die eleganteste Lösung, daß diese in eine kleine Extra-Tabelle die Primärschlüssel der geänderten Datensätze einträgt.
Aus dieser Tabelle kann die Delphi-Anwendung dann schnell erfahren, was sich geändert hat/neu eingefügt wurde und nach Behandlung der betr. Datensätze diese Hilfstabelle leeren.


Narses - Sa 10.01.15 21:59

Moin!

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Wenn Du Zugriff auf die PHP-Skripte hast (diese also selber ändern kannst)
Ich habe (bzw. werde) sie schreiben, also: ja, geht. ;)

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
wäre m.E. nach die eleganteste Lösung, daß diese in eine kleine Extra-Tabelle die Primärschlüssel der geänderten Datensätze einträgt.
Wenn ich das richtig sehe, unterscheidet sich das konzeptionell nicht von Martok´s Vorschlag:
user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
eine gesonderte Event-Liste (=Tabelle), in der alle Events abgelegt werden
Und damit bin ich wieder beim Pollen. :nixweiss: Genau das wollte ich aber eigentlich vermeiden. Die Kunst ist also, das DB-Ereignis weiterzureichen. :idea:

cu
Narses


mandras - Sa 10.01.15 22:32

> Die Kunst ist also, das DB-Ereignis weiterzureichen.

Stimmt ja, aber Aufwand vs. Nutzen kannst nur Du beurteilen.

Wenn zB die Datenbank stark frequentiert ist würde bei der einfachsten Lösung eine ganze Menge Events anfallen. Könnte man zwar irgendwie zusammenfassen, bedeutet aber Mehraufwand.
Außerdem ist es doch meist so: MySQL liegt auf Server mit fester IP bzw. DNS-Eintrag, insofern immer leicht zu erreichen.
Die Delphi-Anwendung meist an dynamischer IP. Also mehr Aufwand, wenn der DB-Server sein Event losschicken will.
Permanente TCP-Verbindung DB-Server // Delphi-Rechner: Machbar, aber was tun bei Verbindungsproblemen?
-> Neuaufbau. Aber sind inzwischen Events verloren gegangen? Kann man natürlich abfangen durch serverseitige Protokollierung.


Narses - Sa 10.01.15 22:45

Moin!

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
> Die Kunst ist also, das DB-Ereignis weiterzureichen.
Stimmt ja, aber Aufwand vs. Nutzen kannst nur Du beurteilen.
Das Problem ist: wie mache ich es denn überhaupt (also das Weiterreichen eines DB-Ereignisses von einem DB-Client zum anderen [konkret: MySQL])? :gruebel: Wenn ich dazu Alternativen habe, kann man auch den Aufwand beurteilen. ;) Bisher steht ja nur Polling (mehr oder weniger optimiert) im Raum. :lupe: Die Lösungen auf Basis von "bescheid sagen" sind ja alle ausserhalb des DB-Layers. :idea:

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Wenn zB die Datenbank stark frequentiert ist würde bei der einfachsten Lösung eine ganze Menge Events anfallen. Könnte man zwar irgendwie zusammenfassen, bedeutet aber Mehraufwand.
Hm, ich kann dir grad nicht folgen. :oops: In welchem Zusammenhang steht denn die Abfrage-Frequenz zur Weiterleitung von Ereignissen? :gruebel:

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
MySQL liegt auf Server mit fester IP bzw. DNS-Eintrag, insofern immer leicht zu erreichen.
Die Delphi-Anwendung meist an dynamischer IP. Also mehr Aufwand, wenn der DB-Server sein Event losschicken will.
Das hab ich bisher noch nicht verraten ;), aber in diesem Fall ist das kein Problem. Sowohl der MySQL- als auch der Delphi-Server sind well-known-hosts, die sehen sich also immer (ist ein Hochverfügbarkeits-System). An dem Delphi-Server hängen dann erst "dynamische" Clients dran, die sind aber erstmal vernachlässigbar.

cu
Narses


Nersgatt - So 11.01.15 11:22

Ist die Verwendung von MySql in Stein gemeißelt?
Firebird hat Events, die Du per Trigger auslösen kannst. Der Client kann sich für die Events registrieren und wird dann informiert, wenn eines der Events auftritt.

Sonst wäre eventuell eine weitere Schicht anzudenken, die einerseits die Daten vom PHP-Script entgegennimmt und in die Datenbank speichert und andererseits ggf. Client über die daraus resultierenden Events informiert (unabhängig von der Datenbank, sondern mit einem eigenen Protokoll). Die Clients müssten dann bei dieser Schicht ihr Interesse an dem Event verkünden. Das wäre praktisch das Firebirdkonzept selbst programmiert.

Edit: Eine weitere Idee wäre vielleicht, das Polling durch einen Dienst zu erledigen, der dann seinerseits die Clients informiert. Damit hast Du so ein Zwischending. Der Vorteil ist, dass der Pollingdienst keine Netzwerklast erzeugt, wenn er auf dem selben Rechner wie die Datenbank läuft. Und außerdem würde dann auch nur ein Datenbankclient pollen und nicht jeder Client für sich. Der Pollingclient kann ja dann die anderen Clients informieren.


Narses - So 11.01.15 16:17

Moin!

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Firebird hat Events, die Du per Trigger auslösen kannst. Der Client kann sich für die Events registrieren und wird dann informiert, wenn eines der Events auftritt.
Na kuck mal, gibt ja doch sowas wie "Events" in Datenbanken. ;)

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Ist die Verwendung von MySql in Stein gemeißelt?
Nunja, nicht in Basalt, aber in Calcit... :? Das System ist schon komplett von mir, insofern lege ich fest, was da läuft. Aber den Webserver gibt´s schon länger und da läuft auch ziemlich viel anderes drüber, das tauscht man jetzt nicht mehr so einfach aus... :nixweiss:

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Und außerdem würde dann auch nur ein Datenbankclient pollen und nicht jeder Client für sich.
Nochmal zum Verständnis: Es gibt den Webserver, der läuft mit PHP und MySQL, dann gibt es den Delphi-Server, der soll seine Daten gemeinsam mit dem Webserver in der MySQL-DB halten. Erst an dem Delphi-Server hängen dann weitere Delphi-Clients und was die da machen, ist völlig egal. :idea: Der Webserver und der Delphi-Server sind VMs, die auf dem gleichen HA-Cluster laufen, die sind also praktisch wie eine gemeinsame Maschine (sind sie zwar aus bestimmten Gründen in der Produktionsumgebung nicht, aber man könnte in einer Testumgebung beide auf einer Maschine betreiben).

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Sonst wäre eventuell eine weitere Schicht anzudenken, die einerseits die Daten vom PHP-Script entgegennimmt und in die Datenbank speichert und andererseits ggf. Client über die daraus resultierenden Events informiert (unabhängig von der Datenbank, sondern mit einem eigenen Protokoll).
Hm, da hab ich noch gar nicht drüber nachgedacht. :gruebel: Interessanter Ansatz, muss ich mal durchdenken... :idea:

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Die Clients müssten dann bei dieser Schicht ihr Interesse an dem Event verkünden. Das wäre praktisch das Firebirdkonzept selbst programmiert.
Wie gesagt, der einzige "Client", der über Daten-Ereignisse vom Webserver zu informieren wäre, ist der Delphi-Server, also genau ein Dienst. Da die beide schon DB-Clients sind, hatte ich gehofft, das auf diesem Layer elegant erledigen zu können, ohne selbst weitere Layer reinziehen zu müssen. :|

cu
Narses


Delete - So 11.01.15 16:36

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Tja, beim Thread-Titel hab ich mir schon einen abgebrochen, mit Suchenworten für Tante Google ist´s gleich ganz vorbei... :? ich glänze mal wieder mit meinem mangelhaften Datenbank-Konzept-Wissen :( und bin auf eure Hilfe angewiesen... :flehan:

Man kann halt nicht alles wissen :wave:

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe eine MySQL-DB, auf die greift ein Webserver-Prozess per PHP und eine Delphi-Anwendung per mysql.dll zu. Der Webserver-Prozess verarbeitet HTTP-Requests und dabei entstehen "Ereignisse" (ein Feld ändert seinen Wert), darauf soll die Delphi-Anwendung reagieren. Aber möglichst ereignisorientiert, nicht per Pollen der Tabellen. :shock: Wie macht man sowas?! :nixweiss: Bitte einen Denkanstoß oder Konzeptvorschlag... :eyes:

Zwar arbeite ich nur selten mit MySQL (vor allem wegen der DLL-Lizenz-Falle), weiß aber, daß auch MySQL Events versenden kann. Schau dir doch mal diese Seite an, die den Event-Scheduler von MySQL [http://dev.mysql.com/doc/refman/5.1/en/events-configuration.html] behandelt. Wenn ich mit Firebird Events versenden will, lege ich den Event zuvor in der Firebird-Datenbank fest und reagiere mit einer Event-Komponente im Delphi-Programm darauf. Alle aktiven Clients erhalten dann diesen Event und es poppt z.B. eine Message-Box auf: "Der Anwender XXYZ hat sich heute, am 11. Januar 2014 um 15:36:23 angemeldet" oder was auch immer ...

Wie das genau bei MySQL geht, weiß sicher jemand anders besser als ich :roll:


Nersgatt - So 11.01.15 19:33

user profile iconPerlsau hat folgendes geschrieben Zum zitierten Posting springen:

Zwar arbeite ich nur selten mit MySQL (vor allem wegen der DLL-Lizenz-Falle), weiß aber, daß auch MySQL Events versenden kann.

Bei MySql ist der Begriff "Event" etwas anders belegt, als bei Firebird. Bei MySql kannst Du es eher wie einen Scheduler sehen, der regelmäßig irgend welche Aufgaben erledigt. Und mit regelmäßig ist stündlich, wöchentlich, an einem bestimmten Tag, etc. zu sehen.
Das hat mit den Events wie ich sie für Firebird oben beschrieben habe, nichts zu tun.


Delete - So 11.01.15 20:43

Okay, dann war das eben ein Schuß in den Ofen :roll:

(Soll man ja im Winter eher vermeiden, wenn er Ofen ausgeht, wird's nämlich arschkalt.)


mandras - So 11.01.15 20:57

Wobei man die Firebird-Events auch nicht für alles brauchen kann:

Ein Event wird pro Transaktion maximal ein mal an die Clients übertragen, zusammen mit der Anzahl, wie oft das Event in der Transaktion getriggert wurde.

Leider kann man dem Event nicht zB die ID des neu eingetragenen Records mitgeben.
Damit wissen die Clients auch nur "in Tabelle X wurde eingefügt", mehr aber auch nicht.

Mit "frequentiert" meine ich weiter oben natürlich Änderungs/Einfügeoperationen.