Forum: PC-Programmierung SQL: Suche Primary-Key für Logging bei dezentraler Datenbank


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Alexander K. (alexander_43)


Bewertung
-1 lesenswert
nicht lesenswert
Hallo Zusammen!

Zum Loggen von Ereignissen auf mehreren Raspberry Pi's habe ich bisher 
über den Raspberry PI einen Zentralen Server mit der SQL Datenbank 
angesprochen. Die Datenbank war also einmal im System vorhanden. 
Aufgrund der Ausfallsicherheit möchte ich nun die Datenbank 1:1 
gespiegelt auf jedem PI installieren und durch einen bidirektionalen 
Synchronisationsdienst den Austausch zwischen dem Server und den Clients 
regeln. Da die Datenbank nicht sonderlich groß ist, spielt die 
Systemperformance keine Rolle und so soll auf jedem Client und dem 
Server die Datenbank gespiegelt sein.
Mein Problem ist, dass ich für die fortlaufende Logging-Tabelle einen 
Primary Key brauche, der einmalig in der Tabelle ist. Ich kann also nur 
schwer eine fortlaufende Nummerierung nehmen, da beim gleichzeitigen 
Auftreten zweier Ereignisse auf verschiedenen Clients es einen Konflikt 
mit einer gleichen ID (Primary Key) beim Synchronisieren untereinander 
gibt. Ich suche also eine Möglichkeit, dieses Problem zu umgehen. 
Eigentlich brauche ich gar keinen Primary Key, aber ohne geht es meines 
Wissens nach nicht?

Ich suche also Tipps für eine mögliche Lösung dieses Problems.

Vielen Dank für eure Antworten im Voraus!

: Bearbeitet durch User
von Hmmm (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Multi-Master-Replikation ist heikel. Besser geht es mit einer Master- 
und einer Slave-Datenbank. Bei einem Ausfall wird dann auf die 
Slave-Datenbank umgeschaltet und diese so lange genutzt, bis der Master 
(nach manuellem Eingriff) wieder läuft.

Falls es unbedingt Multi-Master sein muss: Fortlaufende ID für lokale 
Nutzung, zusätzlich eine systemweit eindeutige ID (z.B. durch getrennte 
Nummernbereiche) vergeben.

von Ergo70 (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Ganz habe ich das nicht verstanden. Wenn jetzt alles zentral gespeichert 
wird, brauchst Du doch auch eine Möglichkeit, die Einträge 
auseinanderzuhalten, z.B. die Hostnamen oder so. Das, zusammen mit z.B. 
den Zeitstempeln ist der Primärschlüssel. Dann auf den Master senden und 
auf die Knoten replizieren. Wenn der Master ausfällt, wird einer der 
Knoten Master, bis der wieder da ist. Multimaster ist noch trickier, da 
musst Du konfliktlösungsstrategien implementieren. Es sollte auch klar 
sein, das keine der beiden Lösungen gegen das Split-Brain Problem gefeit 
ist, falls Netzwerkpartitionen auftreten und sich Knoten eine Weile 
nicht sehen.

von Jan H. (j_hansen)


Bewertung
1 lesenswert
nicht lesenswert
GUID

Wobei die anderen Lösungen hier (Nummernbereiche, Key aus mehreren 
Feldern, gar kein PK) auch gehen, aber GUID wäre mMn die schönste 
Lösung.

von Alexander K. (alexander_43)


Bewertung
-1 lesenswert
nicht lesenswert
Ergo70 schrieb:
> Ganz habe ich das nicht verstanden. Wenn jetzt alles zentral gespeichert
> wird, brauchst Du doch auch eine Möglichkeit, die Einträge
> auseinanderzuhalten, z.B. die Hostnamen oder so. Das, zusammen mit z.B.
> den Zeitstempeln ist der Primärschlüssel.

Meine Anwendung ist ein Zutrittskontrollsystem. Jeder Client verwaltet 
bis zu acht Türen mit entsprechendem Kartenleser etc.. Bisher werden die 
Ereignisse zentral im Server protokolliert. Nun möchte ich aber dass 
auch beim Ausfall des Netzwerkes das System weiter funktioniert. Daher 
die Idee, die Datenbank auf allen Clients zu spiegeln um so auch autark 
arbeiten zu können. Wenn das Netzwerk dann wieder verfügbar ist, so 
sollen die Ereignisse mit dem Server synchronisiert werden. Und genau 
hier liegt das Problem, einen eindeutigen Primary Key zu generieren. 
Jeder Client hat ja seine eigene IP und da wäre es mir am liebsten, 
anhand eines Zeitstempels und der IP einen Primary Key zu erstellen, der 
nur einmal auftreten kann.

von Dirk K. (merciless)


Bewertung
-1 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Eigentlich brauche ich gar keinen Primary Key, aber ohne geht es meines
> Wissens nach nicht?
Du bist nicht gezwungen, einen Primary Key anzulegen.
Gerade bei einer Logging-Tabelle fällt mir gerade
kein Grund ein. PKs sind halt dann notwendig,
wenn ich Daten auf mehrere Tabellen verteile und joinen
muss oder sicherstellen muss, dass ein Eintrag eindeutig
wird (z.B. ein Auftrag in einer Auftrags-Tabelle, da darf
es nur einen mit der Nr 4711 geben).

Wie sieht denn so ein Logging-Eintrag aus?

merciless

von Hmmm (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Warum willst Du auf jedem Client eine Datenbank laufenlassen? Einfach 
bei einem Ausfall lokal cachen, im einfachsten Fall im RAM, und dann 
beim Auftauchen der Datenbank wegschreiben wie sonst auch.

von Theor (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Ergo70 schrieb:
>> Ganz habe ich das nicht verstanden. Wenn jetzt alles zentral gespeichert
>> wird, brauchst Du doch auch eine Möglichkeit, die Einträge
>> auseinanderzuhalten, z.B. die Hostnamen oder so. Das, zusammen mit z.B.
>> den Zeitstempeln ist der Primärschlüssel.
>

> [...] Und genau
> hier liegt das Problem, einen eindeutigen Primary Key zu generieren.
> Jeder Client hat ja seine eigene IP und da wäre es mir am liebsten,
> anhand eines Zeitstempels und der IP einen Primary Key zu erstellen, der
> nur einmal auftreten kann.

Und (fast) genau so, solltest Du es eigentlich machen können und damit 
einen eindeutigen Schlüssel erhalten. Allerdings unter dem Vorbehalt, 
dass bei 8 Zugängen evtl. zwei oder mehr Zugänge im schlechtesten Fall 
gleichzeitig benutzt werden. Ich würde noch die Nummer (oder sonstige 
ID) des Zuganges zu dem Schlüssel hinzufügen (wobei die gleiche Nummer, 
wegen der zusätzlich vorhandenen IP durchaus bei mehreren RPis vergeben 
sein darf).

Es scheint, als ob da bei Dir ein Zweifel über die Vorgehensweise 
besteht. Ich kann nur leider nicht erkennen, worin er genau liegt.

von Theor (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
Ah. Die Frage ist wohl, ob man einen Primärschlüssel überhaupt braucht.

Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein 
Eintrag mehrfach vorkommen darf.

Daraus ergibt sich zwangsweise, dass es eine weitere Spalte (oder eine 
Kombination von Spalten) gibt, in denen die Werte niemals mehrfach in 
verschiedenen Einträgen auftreten.

von Imonbln (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
gib doch jeden Gerät auf welchen eine Datenbank läuft eine uuid, dann 
Berechnest du einen Kryptographisch hinreichend sichern Hash aus der 
UUID + Timestamp + serialisierte Meldung, das ist dann dein Primär 
schlüssel.

Wenn du dann auch noch den letzten Hash mit in den aktuellen Hash 
einfließen lässt, hast du auch schon eine Blockchain (TM). jetzt noch 
die letzten Bekannten Hashvalues der Anderen Instanzen, dann hast du 
auch eine verteilte Blockchain ;)

Na das mit der Blockchain, ist natürlich nur so halb ernst gemeint, aber 
gerade Logs von Security relavanten Geräten ist einer der wenigen Fälle 
wo man über eine dedizierte Blockchain nachdenken kann, um bei einen 
Vorfall die Logeinträge qualifizieren zu können. Mein Vorschlag fehlen 
natürlich noch ein paar Signaturen um eine vollwertige Blockhain für 
logs zu bauen.

von Dennsi W. (googoo)


Bewertung
-1 lesenswert
nicht lesenswert
Theor schrieb:
> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
> Eintrag mehrfach vorkommen darf.

Und dazu ist der Schlüssel da ;)

Nimm eine fortlaufende Nummer und trage zusätzlich für jede Station eine 
eindeutige Nummer 1...x mit ein und beim kopieren lässt die fortlaufende 
Nummer aber weg sondern bildest in deiner Sammeltabelle einen index über 
Station, Zeitstempel. So hast du alles bei'nander

von Alexander K. (alexander_43)


Bewertung
-1 lesenswert
nicht lesenswert
Dirk K. schrieb:
> Wie sieht denn so ein Logging-Eintrag aus?

Geloggt wird in jeweils einer Spalte:
-Leser-ID (ist einmalig im System und wird aus einer anderen Tabelle 
anhand der IP und der internen Nummer 1-8 am Kartenleser-Bus des 
Zutritts-Clients bestimmt)
-ID der Zutrittskarte
-Name der Person
-Datum und Uhrzeit
-Ereignis (String)

Theor schrieb:
> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
> Eintrag mehrfach vorkommen darf.
>
> Daraus ergibt sich zwangsweise, dass es eine weitere Spalte (oder eine
> Kombination von Spalten) gibt, in denen die Werte niemals mehrfach in
> verschiedenen Einträgen auftreten.

Das dürfte bei der Kombination mehrerer Spalten kein Problem sein, 
lediglich eine einzelne einmalige wird schwierig. Daher die Frage, wie 
ich die Eindeutigkeit schaffe.

Hmmm schrieb:
> Warum willst Du auf jedem Client eine Datenbank laufenlassen? Einfach
> bei einem Ausfall lokal cachen, im einfachsten Fall im RAM, und dann
> beim Auftauchen der Datenbank wegschreiben wie sonst auch.

Die Datenbank enthält neben dem Logging auch noch Informationen über die 
Zutrittsberechtigungen, welche allerdings nur zentral vergeben werden 
und daher in der Synchronisation kein Problem darstellen. Die 
Informationen müssen aber natürlich bei einem Ausfall des Netzwerkes 
trotzdem lokal vorhanden sein.

von Theor (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
Dennsi W. schrieb:
> Theor schrieb:
>> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
>> Eintrag mehrfach vorkommen darf.
>
> Und dazu ist der Schlüssel da ;)
>

Genau.:-)

> Nimm [...]

Mir ist bekannt, was man da macht. Ich bin nur nicht der TO. :-)

von Theor (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Dirk K. schrieb:
>> Wie sieht denn so ein Logging-Eintrag aus?
>
> Geloggt wird in jeweils einer Spalte:
> -Leser-ID (ist einmalig im System und wird aus einer anderen Tabelle
> anhand der IP und der internen Nummer 1-8 am Kartenleser-Bus des
> Zutritts-Clients bestimmt)
> -ID der Zutrittskarte
> -Name der Person
> -Datum und Uhrzeit
> -Ereignis (String)
>
> Theor schrieb:
>> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
>> Eintrag mehrfach vorkommen darf.
>>
>> Daraus ergibt sich zwangsweise, dass es eine weitere Spalte (oder eine
>> Kombination von Spalten) gibt, in denen die Werte niemals mehrfach in
>> verschiedenen Einträgen auftreten.
>
> Das dürfte bei der Kombination mehrerer Spalten kein Problem sein,
> lediglich eine einzelne einmalige wird schwierig. Daher die Frage, wie
> ich die Eindeutigkeit schaffe.
>
> [...]

OK.

Wie schon von anderen geschrieben und auch von Dir. Eine Kombination von 
Spalten wählen, die in jedem Fall eindeutig sind. (Das hängt in Deinen 
Beispiel auch davon ab, wovor man sich schützen will. Etwa, kopierte 
Zugangskarten etc.).

Aber die Frage ist jetzt beantwortet, oder? Falls nicht, gib noch mal 
Laut. Vielleicht schreibst Du auch noch im Detail, was noch genauer 
beantwortet werden könnte, damit es Dir hilft.

von Theor (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Sorry. Schreibfehler:

"Wie schon von anderen geschrieben und auch von Dir. Eine Kombination 
von
Spalten wählen, die in jedem Fall eindeutig ist." Das 
Eindeutigkeitskriterium bezieht sich auf die Kombination.

von sid (Gast)


Bewertung
-4 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Das dürfte bei der Kombination mehrerer Spalten kein Problem sein,
> lediglich eine einzelne einmalige wird schwierig. Daher die Frage, wie
> ich die Eindeutigkeit schaffe.

das ist doch leicht.. autoincrement mit prefix
und falls Du das prefix nicht via trigger setzen willst (weil es länger 
dauert ;))
setzt Du einen AI startwert einfach hoch genug an,
sagen wir 5000000001
die andere startet schlicht bei 1

bis da ein Wert doppelt auftritt dauert es gewöhnlich eine ganze Weile.

'sid

von Alexander K. (alexander_43)


Bewertung
-1 lesenswert
nicht lesenswert
Theor schrieb:
> Aber die Frage ist jetzt beantwortet, oder? Falls nicht, gib noch mal
> Laut. Vielleicht schreibst Du auch noch im Detail, was noch genauer
> beantwortet werden könnte, damit es Dir hilft.

Danke für eure Antworten!
Ich habe nebenbei etwas recherchiert und kam auf folgende Möglichkeit 
(Variablennamen als Beispiel):

CREATE TABLE tab(
  id INTEGER,
  id2 INTEGER,
  PRIMARY KEY (id,id2)
);

Wenn ich dies für meine Tabelle mit den relevanten Werten umsetzte, dann 
brauche ich ja gar nicht zwingend eine separate Spalte für die ID als 
Primary Key sondern muss nur sicherstellen, dass die angegebenen Spalten 
in ihrer Konstellation jeweils einmalig sind? Ich kannte es bisher bloß 
so, als Primary Key eine Variable anzugeben.

von Oszi50 (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Nein,

du denkst falsch!

Deine Datenbank auf dem Master-Pi wird zu einer bestimmten Uhrzeit zu 
den Slaves übertragen. Am Besten die Datenbank auf 7 Tage aufteilen, so 
kann man noch rechtzeitig das Backup fahren.

von Theor (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Theor schrieb:
>> Aber die Frage ist jetzt beantwortet, oder? Falls nicht, gib noch mal
>> Laut. Vielleicht schreibst Du auch noch im Detail, was noch genauer
>> beantwortet werden könnte, damit es Dir hilft.
>
> Danke für eure Antworten!
> Ich habe nebenbei etwas recherchiert und kam auf folgende Möglichkeit
> (Variablennamen als Beispiel):
>
> CREATE TABLE tab(
>   id INTEGER,
>   id2 INTEGER,
>   PRIMARY KEY (id,id2)
> );

Ganz grob ist das der Ansatz. Ja. Aber dazu ist Weiteres zu sagen.

>
> Wenn ich dies für meine Tabelle mit den relevanten Werten umsetzte, dann
> brauche ich ja gar nicht zwingend eine separate Spalte für die ID als
> Primary Key sondern muss nur sicherstellen, dass die angegebenen Spalten
> in ihrer Konstellation jeweils einmalig sind?

Richtig.

Die meisten DBMS bieten an, einen Primärschlüssel selbst zu erzeugen. 
Oder eine Spalte alleine ist offensichtlich, und das passiert doch öfter 
mal, allein eindeutig. Das kann suggerieren, dass dies grundsätzlich 
hinreichend ist.
In Deinem Fall aber geht das erste nur mit zusätzlichen Maßnahmen und 
das zweite gar nicht.

Also suchst Du Dir eine Kombination von Spalten (was Du hier Variablen 
nennst), die so grundsätzlich und über alle Teilsysteme nur einmal 
auftreten kann.

Z.B. auch:
CREATE TABLE tab(
  Leser-ID INTEGER,
  MomentOfAttempt DATETIME,
  PRIMARY KEY (Lesser-ID, MomentOfAttempt)
);

Der Gedanke ist: Es kann ein einem einzelnen Leser nur zu einem 
Zeitpunkt eine Versuch gemacht werden, sich zu authentifizieren. (Das 
muss nicht zutreffen, aber Du schriebst oben, dass in Deinem Fall alle 
Leser systemweit eine eigene ID haben).

Kleiner Hinweis noch. Je nach dem wie lange ein Leseversuch dauert, 
musst Du evtl. auch die Sekunden in den Schlüssel mit aufnehmen.

> Ich kannte es bisher bloß
> so, als Primary Key eine Variable anzugeben.

Wieder was dazu gelernt. Lächel. :-)

von Ergo70 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Selbst wenn das so wäre, z.B. bei einem Key/Value Store, kannst Du immer 
noch mehrere Werte zu einem konkatenieren oder einen Hash benutzen. Und 
relationale Datenbanken erzwingen keinesfalls, das identische Einträge 
nicht mehrfach vorkommen dürfen. Das kann man erzwingen, muß aber nicht.

von c-hater (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Theor schrieb:

> Die Frage ist wohl, ob man einen Primärschlüssel überhaupt braucht.

Das kommt allein darauf an, was der Zweck der Daten ist. Par se benötigt 
man keinen Primärschlüssel. Will man gezielt auf einzelne Datensätze 
zugreifen können, braucht man einen.

Bei Log-Daten sehe ich erstmal nichts, was zwingend Eindeutigkeit 
einzelner Datensätze erfordern würde.

Eine zuverlässige und effiziente Replikation allerdings würde dies 
erfordern.

> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
> Eintrag mehrfach vorkommen darf.

Nein, natürlich nicht. Weil es halt auch unzählige Anwendungen gibt, bei 
denen das durchaus zulässig sein könnte. Wie gesagt: es hängt vom Zweck 
der Daten ab.

von Dirk K. (merciless)


Bewertung
-1 lesenswert
nicht lesenswert
Theor schrieb:
> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
> Eintrag mehrfach vorkommen darf.
Das ist einfach nur falsch.

Alexander K. schrieb:
> Dirk K. schrieb:
>> Wie sieht denn so ein Logging-Eintrag aus?
>
> Geloggt wird in jeweils einer Spalte:
> -Leser-ID (ist einmalig im System und wird aus einer anderen Tabelle
> anhand der IP und der internen Nummer 1-8 am Kartenleser-Bus des
> Zutritts-Clients bestimmt)
> -ID der Zutrittskarte
> -Name der Person
> -Datum und Uhrzeit
> -Ereignis (String)
Du könntest einen zusammengesetzten PK verwenden
(Leser-ID, CardID, Timestamp), aber stellt sich
mir immer noch die Frage nach dem warum? Was soll
der verhindern oder verbessern?

Wie werden die Daten ausgewertet?

merciless

: Bearbeitet durch User
von Pucki (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Wieso soll das so kompliziert sein.

So wie ich das verstanden habe, hat jeder Zugangspunkt eine eigene DB.
Also musst du nur von den Zugangspunkt aus, regelmäßig (oder auf 
Anforderung) ein Abgleich mit den Hauptserver machen. Alternativ schickt 
man die Daten gleich zum Server.

Dazu brauchst du nur die Zeitangabe (auf die Sekunde genau) und die 
Terminal-Nr.

Die Zeitangabe und die restlichen Daten speicherst du pro Terminal auf 
den selbigen.  In der Server Datenbank werden beim Abrufen der Daten 
überprüft ob diese Zeitangabe schon vorliegt. Wenn ja, vergiss es, wenn 
nein lege Datensatz an (mit Terminal-nr).

Nun kann man einfach auf den Server eine Routine schreiben, mit der ein 
Terminal bei einen Komplettausfall mit seinen Daten wieder gefüttert 
wird. FERTIG.

Dadurch hat man ein Gegenseitiges Backup-System. Und alle paar Monate 
brennst du mal eine DVD mit den alten Daten (vom Server) wegen 
Nachvollziehbarkeit und schickst ein Clear an die Terminals damit da die 
DB nicht überläuft.

Gruß

   Pucki

von Theor (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Dirk K. schrieb:
> Theor schrieb:
>> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
>> Eintrag mehrfach vorkommen darf.
> Das ist einfach nur falsch.
>
> [...]

Tatsächlich? Aha.
Welche Datenbank lässt das zu?

von 50c (Gast)


Bewertung
3 lesenswert
nicht lesenswert
Theor schrieb:
> Welche Datenbank lässt das zu?

...so ziehmlich jede!

von Theor (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Theor schrieb:
> Dirk K. schrieb:
>> Theor schrieb:
>>> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
>>> Eintrag mehrfach vorkommen darf.
>> Das ist einfach nur falsch.
>>
>> [...]
>
> Tatsächlich? Aha.
> Welche Datenbank lässt das zu?

Ah. MySQL und MariaDB erlauben das offenbar. Wusste ich vorher nicht. 
Danke für den Hinweis.

Hatte mich jahrzehntelang immer bemüht keine doppelten Einträge 
vorkommen zu lassen, weil das bei meinen Anwendungen ein Fehler gewesen 
wäre. Da habe ich mich dazu verleiten lassen, anzunehmen, dass die DBMS 
das nicht zulässt.

von c-hater (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Theor schrieb:

> Hatte mich jahrzehntelang immer bemüht keine doppelten Einträge
> vorkommen zu lassen, weil das bei meinen Anwendungen ein Fehler gewesen
> wäre.

Ernsthaft: jahrzehntelang? Oh oh...

Wer über Jahrzehnte hinweg nichts dazulernt, nur weil die konkreten 
Anwendungen das gerade nicht erfordern...

Ich will nicht weiter ausführen, was das bedeutet. Würde eh' als 
"Beleidigung" gelöscht werden, auch wenn es nur die objektive Wahrheit 
ist...

von Hannes J. (Firma: professional Professional) (pnuebergang)


Bewertung
-1 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Danke für eure Antworten!
> Ich habe nebenbei etwas recherchiert und kam auf folgende Möglichkeit
> (Variablennamen als Beispiel):
>
> CREATE TABLE tab(
>   id INTEGER,
>   id2 INTEGER,
>   PRIMARY KEY (id,id2)
> );

Noch mal die Frage, andere haben sie auch schon gestellt:

Was willst du mit dem Primary Key, besonders bei deiner Anwendung, wo es 
um das Aufzeichnen von Logging-Informationen geht?

Zweitens, aus den von dir zu loggenden Daten:
Alexander K. schrieb:
> Geloggt wird in jeweils einer Spalte:
> -Leser-ID (ist einmalig im System und wird aus einer anderen Tabelle
> anhand der IP und der internen Nummer 1-8 am Kartenleser-Bus des
> Zutritts-Clients bestimmt)
> -ID der Zutrittskarte
> -Name der Person
> -Datum und Uhrzeit
> -Ereignis (String)

kann man sich direkt einen basteln (Leser-ID mit Datum/Uhrzeit). Nur, 
wozu?

Drittens, "ID der Zutrittskarte" und "Name der Person" sind redundante 
Informationen. Das ist eine Todsünde im Datenbank-Entwurf. Die ID als 
Foreign Key reicht. Wenn man den Namen will sieht man mit der ID in 
einer Namenstabelle nach (dort die ID als Primary Key). Das nennt sich 
eine Relation. Dafür sind diese Relationalen Datenbanken gemacht.

> Wenn ich dies für meine Tabelle mit den relevanten Werten umsetzte, dann
> brauche ich ja gar nicht zwingend eine separate Spalte für die ID als
> Primary Key

Du brauchst für das Loggen alleine überhaupt keinen Primary Key in der 
Tabelle. Nochmal, hast du irgend einen Grund, warum du da einen Primary 
Key brauchst? Nicht haben möchtest, sondern brauchst?

von Alexander K. (alexander_43)


Bewertung
0 lesenswert
nicht lesenswert
Danke für eure zahlreichen Antworten!

Hannes J. schrieb:
> Noch mal die Frage, andere haben sie auch schon gestellt:
>
> Was willst du mit dem Primary Key, besonders bei deiner Anwendung, wo es
> um das Aufzeichnen von Logging-Informationen geht?

Ich will ja gar keinen Primary Key, wusste aber nicht, dass ich ihn 
weglassen kann. Daher hier die Frage. Dank euren Informationen werde ich 
das ganz weglassen.

Kann ich daher einfach die Primary-Key-Anweisung entfallen lassen so wie 
hier im Beispiel?
CREATE TABLE tab(
  Leser-ID INTEGER,
  MomentOfAttempt DATETIME
);

von blib (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Kann ich daher einfach die Primary-Key-Anweisung entfallen lassen so wie
> hier im Beispiel?

Kann man wohl. Macht aber nur Sinn bei write-only-Datenbanken, denn ohne 
PK wird's schwierig aus der Datenbank etwas zu lesen. Wenn Du einen 
bestimmten Zeitpunkt suchst wird er jedesmal die komplette Tabelle 
sortieren müssen. Es tut auch nicht weh einen PK zu setzten, zumindest 
auf Datetime, Leser. Und einen einfachen Schlüssel auf Leser, Datetime, 
dann bist du gut versorgt ;)

von blib (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Es kommt halt drauf an wie du auslesen willst. Interessiert ob sich 
jemand sich wann wo einloggt müssen in dieser Reihenfolge die Felder in 
den Schlüssel. (Person, Zeit) Willst du wissen was an einem Leser 
passiert, Key auf (Leser, Zeit). Willst Du wissen wie oft jemand an 
welchem Leser durchgeht Key auf (Person, Leser,( Zeit)). So einfach ist 
das. Wenn du schnell lesen willst macht es mitunter Sinn PrimaryKey und 
noch einen zweiten Index zu setzten, wobei jedes Feld Speicherplatz 
benötigt. Auch werden wie schon geschrieben wurde Namen nur einmal in 
ner Tabelle gespeichert und darauf über die ID verlinkt. Zeit ist immer 
in unixtime dann hast du kein Stress mit Sommer/Winterzeit.

von Devon Miles (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wieso muss es unbedingt SQL sein?

Das klingt für mich nach Zeitreihendatenbank. Influx, Prometheus etc.

von Ergo70 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
blib schrieb:
> Macht aber nur Sinn bei write-only-Datenbanken, denn ohne PK wird's
> schwierig aus der Datenbank etwas zu lesen. Wenn Du einen bestimmten
> Zeitpunkt suchst wird er jedesmal die komplette Tabelle sortieren
> müssen.

Quatsch. Ein non-unique Index würde da reichen, dafür braucht es keinen 
PK.

von blub (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ergo70 schrieb:
> Quatsch. Ein non-unique Index würde da reichen, dafür braucht es keinen
> PK.

LOL, Der braucht dann mehr Speicher als nur der PK ;)
Die Reihenfolge in der die Grunddaten der Tabelle abgespeichert werden 
IST der PK ;) Danach kommen erst indexe. Man muss keinen PK setzten, es 
bringt aber viel Performance beim Lesen/Suchen.

von Theor (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Alexander K. schrieb:
> Danke für eure zahlreichen Antworten!
>
> Hannes J. schrieb:
>> Noch mal die Frage, andere haben sie auch schon gestellt:
>>
>> Was willst du mit dem Primary Key, besonders bei deiner Anwendung, wo es
>> um das Aufzeichnen von Logging-Informationen geht?
>
> Ich will ja gar keinen Primary Key, wusste aber nicht, dass ich ihn
> weglassen kann. Daher hier die Frage. Dank euren Informationen werde ich
> das ganz weglassen.
>
> Kann ich daher einfach die Primary-Key-Anweisung entfallen lassen so wie
> hier im Beispiel?
>
>
> CREATE TABLE tab(
>   Leser-ID INTEGER,
>   MomentOfAttempt DATETIME
> );
> 

Versuchs einfach.

Nochmal kurz an Dich, Alexander, ein Sorry.

Ich habe mich durch den Satz von Dir:
"... dass ich für die fortlaufende Logging-Tabelle einen
Primary Key brauche, ..." und durch meine eigene grundsätzliche 
Verwendung von Primary Keys irreführen lassen.
Wie hier schon jemand schrieb: in der Regel verwendet man (oder 
jedenfalls ich) Datenbanken um die Daten hinterher abfragen zu können. 
Das geht deutlich schneller, wenn man PKs verwendet.
Ausserdem sind in den Anwendungen, die ich hatte, wie ich schon schrieb, 
mehrfache gleiche Einträge aus dem Sachzusammenhang heraus, unmöglich 
gewesen.
Wenn ich mich recht erinnere, dann hat Microsoft Access bei der Anlage 
von Tabellen grundsätzlich nach einem Primary Key gefragt. Das hat sich 
bei mir gedanklich festgesetzt.

von Pucki (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
Leg ein Primary Key an.  Nenne ihn ID , integer und auf AUTOMATIK. !!!
Dies führt dazu das die Datenbank automatisch ein Feld mit einer 
EINMALIGEN Zahl versieht. Dies macht immer Sinn bei Datenbanken.

Der Grund ist einfach. Wenn man einen Datensatz ändern will liest man 
die Datensatz mit der ID, und schreibt ihn zurück mit "where ID = ****" 
. Auch gewisse Abfragen in der Datenbank brauchen die ID. Einige 
Datenbanken funktionieren nicht einmal ohne, da sie diese ID für 
temporäre Tabellen (erzeugt durch eine Abfrage) benötigen.

Ergo man erspart sich unnötigen Stress.

Du hast 2 Möglichkeiten.  Entweder du schreibst ein ZWEITEN Primary 
Key selber, z.b. Terminal + Uhrzeit (sekundengenau) ODER du MUST bei 
vielen Abfragen ZWEI Felder abfragen.

Ich persönlich würde BEIDE Varianten machen. Das macht die DB zwar ein 
bisschen größer aber mir als Programmierer das Leben einfacher und 
hinterher die Datenbank sogar schneller. Nämlich dann wenn du eine 
Abfrage nur mit einen Feld regeln kannst.

Gruß

   Pucki

von Pucki (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Nachtrag für Datenbankanfänger.

Beim Anlegen einer Datenbank kann man JEDEN Feld Eigenschaften zuweisen. 
Eine davon ist "Einmalig" , eine andere "Groß und Kleinschreibung 
ignorieren". Es gibt da noch viel mehr.

Wer also einen Datenbank aufbauen will, sollte sich vorher ganz genau 
überlegen wie er die Daten später behandeln will.  Das entscheidet auch, 
wie viele und welche Tabellen er braucht.

Merke : Eine Adressverwaltung ist eine Datenbank, aber eine Datenbank 
ist keine Adressverwaltung.

Ich persönlich CODE meist eine Software um die Datenbank drumherum. Und 
mache nur Änderungen wenn ich zusätzliche Felder vergessen habe.

Anders herum muss man dauernd sein Code anpassen an Stellen wo man schon 
fertig war.

Gruß

   Pucki

von blub (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Pucki schrieb:
> Wenn man einen Datensatz ändern will liest man die Datensatz mit der ID,
> und schreibt ihn zurück mit "where ID = ****"

Das kann man in jedem Fall machen. Das zugreifen auf die ID erpsart 
Tipparbeit, man erkauft es sich dann dadurch dass der zusätzliche Index 
zusätzlich Speicher verbraucht.

Pucki schrieb:
> Entweder du schreibst ein ZWEITEN Primary Key selber, z.b. Terminal +
> Uhrzeit (sekundengenau) ODER du MUST bei vielen Abfragen ZWEI Felder
> abfragen.

Ich hatte oben schon geschrieben was der PK ist. Es gibt nur EINEN, 
daher der Name;) Alles andere sind Indexe;)

Pucki schrieb:
> ODER du MUST bei vielen Abfragen ZWEI Felder abfragen

grundsätzlich hat Pucki da Recht

von Bauform B. (bauformb)


Bewertung
-1 lesenswert
nicht lesenswert
Pucki schrieb:
> Der Grund ist einfach. Wenn man einen Datensatz ändern will liest man
> die Datensatz mit der ID, und schreibt ihn zurück mit "where ID = ****"

Wirklich. Nicht.
Diese Anwendung ist ein Musterbeispiel für eine write-only Datenbank!

von ergo70 (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
blub schrieb:
> LOL, Der braucht dann mehr Speicher als nur der PK ;)

Wenn der zusätzlich zum PK ist, hast Du Recht, aber das macht 
überhaupt keinen Sinn, weil der PK ja seinen eigenen Index anlegt. Ich 
meine einen Index statt eines PK, wenn ein PK nicht möglich ist, weil 
die Daten nicht unique sind.

Die Originalaussage war ja:

> Macht aber nur Sinn bei write-only-Datenbanken, denn ohne PK wird's
> schwierig aus der Datenbank etwas zu lesen. Wenn Du einen bestimmten
> Zeitpunkt suchst wird er jedesmal die komplette Tabelle sortieren
> müssen.

Und das ist und bleibt Quatsch. Ich brauche auch ohne PK keinen full 
table scan, wenn ich einen Index auf mindestens einem Teil der 
Suchargumente anlege,  und der_muß nicht_ unique sein.

Aber mal sehen, 10 Millionen rows, PostgreSQL 12.x:
create table sensor_log ( sensor_log_id serial,
location varchar not null,
reading bigint not null,
reading_date timestamp not null );

insert
  into
  sensor_log (location,
  reading,
  reading_date)
select
  s.id % 1000,
  round(random() * 100),
  current_date + interval '1d' - ((s.id * 10)::text || 's')::interval
from
  generate_series(1, 10000000) s(id);

alter table public.sensor_log add constraint sensor_log_pk primary key (sensor_log_id);

select
  pg_size_pretty (pg_indexes_size('sensor_log'));

-- 214 MB

create table sensor_log ( sensor_log_id serial,
location varchar not null,
reading bigint not null,
reading_date timestamp not null );

insert
  into
  sensor_log (location,
  reading,
  reading_date)
select
  s.id % 1000,
  round(random() * 100),
  current_date + interval '1d' - ((s.id * 10)::text || 's')::interval
from
  generate_series(1, 10000000) s(id);

create index idx_nonunique_sensor_log_id on
sensor_log
  using btree(sensor_log_id)
select
  pg_size_pretty (pg_indexes_size('sensor_log'));

-- 214 MB

create index idx_nonunique_sensor_log_id on
sensor_log
  using brin(sensor_log_id);

select
  pg_size_pretty (pg_indexes_size('sensor_log'));

-- 56 kB

Also, 214 MB primary-key vs. 214 MB nonunique-index vs. 56 kB 
nonunique-index wenn man ein wenig nachdenkt und die Datenstruktur es 
hergibt. Natürlich sind die Daten in allen Indexen unique, sonst würde 
das mit dem PK ja nicht funktionieren, aber wenn man z.B. 'reading' 
indexiert sind es 215 MB, also ca. 0.5% mehr. Das hängt aber auch vom 
Anwendungsfall, dem verwendeten Datenbanksystem und von den verfügbaren 
Indextypen ab. Dann gibt es ja noch partial indexes, covering indexes... 
Also, Versuch macht kluch.

von blub (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Jo also ID kann man immer haben wenn man nur inserts am Ende macht ist 
das Quasi ein flatfile. Dazu dann zusätzlich Indexe.
Ist aber nicht MEINE persönliche beste Wahl.

Man kann da etwas herumexperimentieren wie es nun am besten ist.

Man kann zB. die Tabelle anlegen mit PK
Uhrzeit, Station, User
und dann weitere indizes für das was man abfragen will
zB.
User, Uhrzeit, Station
Station, User, Uhrzeit

Ein Puzzlespiel;)

von Klaus P. (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Theor schrieb:
> Soweit es mir bekannt ist, erzwingen alle Datenbanksysteme, dass kein
> Eintrag mehrfach vorkommen darf.

Nein, das erzwingen die gängigen DBMS nicht. Umgekehrt - mit einem 
Primärschlüssel erzwingst Du genau das.

Einen Primärschlüssel oder einen UNIQUE Constraint benötigt man bei den 
meisten Systemen, um mit einem Fremdschlüssel darauf zu referenzieren.

Außerdem benötigen viele GUI Tools einen Primärschlüssel oder einen 
UNIQUE Constraint, um Tabellen zu editieren. Auch für die reine 
Darstellung größerer Tabellen benötigt man in der Regel einen 
eindeutigen Schlüssel.

Für ein reines Log brauchst Du daher im Grunde keinen Primärschlüssel. 
Aber eine GUID (UUID) als Primärschlüssel ist bei einem verteilten 
System spätestens dann nützlich, wenn einmal geprüft werden muss, ob bei 
der Synchronisation nichts doppelt impoortiert wurde.

von blub (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
ergo70 schrieb:
> Und das ist und bleibt Quatsch. Ich brauche auch ohne PK keinen full
> table scan, wenn ich einen Index auf mindestens einem Teil der
> Suchargumente anlege,  und der_muß nicht_ unique sein.

Das stimmt aber ich gehe davon aus dass bevor man nen Index anlegt ein 
PK gesetzt wird. PK ist quasi der Erste Index und damit völlig umsonst 
denn in irgendeiner Reihenfolge müssen die Daten ja sowieso 
abgespeichert werden. Sparst also mit PK einen Index.

von blub (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Eine GUID ist auch nix anderes als eine zufällige ID. Ja das mag 
teilweise sinnvoll sein, brauchts aber nicht da Station, Zeit ja immer 
eindeutig ist also auch den Zweck erfüllt.

von blub (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
ergo70 schrieb:
> select
>   pg_size_pretty (pg_indexes_size('sensor_log'));
>
> -- 56 kB

Ja merkste was? Der index kost' nix, weil er heimlich den PK als index 
hernimmt.

von blub (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
ID/GUID KANN als PK sinnvoll sein falls man der Uhr misstraut, kann ja 
sein dass die mal nen Tag zurück springt dann kann man die Daten 
trotzdem retten. Deshalb hat man oft eine fortlaufende Nummer als erstes 
Feld und kann darüber dann die Zeit nachträglich korrigieren. Eine 
zufällige GUID nutzt dann aber nichts da sie keine Information über die 
Reihenfolge enthält.

von ergo70 (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
> Ja merkste was? Der index kost' nix, weil er heimlich den PK als index
> hernimmt.

Nein, denn ich habe die Tabelle natürlich dazwischen mal geDROPpt und 
beim zweiten Test gar keinen PK angelegt. Man beachte das fehlende ALTER 
TABLE ... ADD CONSTRAINT ...

Allerdings habe ich mir die DROP TABLE statements nicht aufgeschrieben, 
daher war das vielleicht nicht ganz klar. Nur, warum sollte ich wohl 
exakt die selbe Tabelle zweimal anlegen wollen, wenn ich keine 
Veränderung daran vornehmen wollte?

Und der letzte Index ist so klein, weil er kein BTREE, sondern ein BRIN 
ist.

https://www.percona.com/blog/2019/07/16/brin-index-for-postgresql-dont-forget-the-benefits/

BRINs sind für natürlich geordnete Daten super, falls man kein UNIQUE 
braucht und mit partial table scans leben kann. Meistens kann man das im 
Zeitalter der SSD aber, zumal man die Blockgröße anpassen kann.

>Eine
>zufällige GUID nutzt dann aber nichts da sie keine Information über die
>Reihenfolge enthält.

Auch nicht ganz korrekt, vgl.

COMB: https://www.informit.com/articles/article.aspx?p=25862

und

https://github.com/tvondra/sequential-uuids

von Sheeva P. (sheevaplug)


Bewertung
0 lesenswert
nicht lesenswert
Hmmm schrieb:
> Multi-Master-Replikation ist heikel. Besser geht es mit einer Master-
> und einer Slave-Datenbank.

Naja...

> Bei einem Ausfall wird dann auf die
> Slave-Datenbank umgeschaltet und diese so lange genutzt, bis der Master
> (nach manuellem Eingriff) wieder läuft.

Ja, aber: wie wird das umgeschaltet? Wie wird eine Split-Brain-Situation 
verhindert? Wie werden Clients über einen ausgefallenen Master 
informiert?

> Falls es unbedingt Multi-Master sein muss: Fortlaufende ID für lokale
> Nutzung, zusätzlich eine systemweit eindeutige ID (z.B. durch getrennte
> Nummernbereiche) vergeben.

Moderne geclusterte Softwaresysteme können das oft von Haus aus... Think 
Redis, Elasticsearch, PostgreSQL-XL, um nur ein paar zu nennen.

von Ergo70 (Gast)


Bewertung
0 lesenswert
nicht lesenswert

von blub (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Mit Kanonen auf Spatzen

von Sheeva P. (sheevaplug)


Bewertung
1 lesenswert
nicht lesenswert
Ergo70 schrieb:
> Ja, trivial ist es nicht, aber machbar:
>
> 
https://de.slideshare.net/mobile/srihari29691/on-the-building-of-a-postgresql-cluster

Nicht alles, was machbar ist, ist auch klug. Die dort beschriebene 
Lösung skaliert nicht horizontal bezüglich der Schreiblast, und die 
gesamte Herangehensweise und Implementierung dort erscheinen mir, mit 
Verlaub, ein wenig... hemdsärmelig. Und obendrein bietet AWS, bei denen 
sie dieses Projekt hosten, ja selbst einen Haufen Datenbanken an, 
darunter Allrounder ähnlich den klassischen RDBMS, aber auch 
Key-Value-Stores, In-Memory-Datenbanken, Timeseries und weitere, von 
denen sehr viele Replikation (Hochverfügbarkeit) und Sharding 
(horizontale Skalierbarkeit) schon von Hause aus direkt unterstützen...

Und, nunja, PostgreSQL hat schon seit vielen Jahren Features, mit denen 
sich eine Hochverfügbarkeit herstellen läßt, von einfachen Ansätzen mit 
DRBD über komplexe Setups mit Corosync, Heartbeat/Pacemaker, STONITH und 
Co.... Aber heutzutage gibt es stattdessen auch eine "echte" 
Clusterversion von PostgreSQL, nämlich PostgreSQL-XL, die keine 
klassische High Availability, sondern Distributed Computing nutzt. Daher 
kann sie durch ihre Replikation die Hochverfügbarkeit und durch Sharding 
horizontale Skalierbarkeit sicherstellen -- und bietet all die vielen 
feinen Features an, die dieser modernere Ansatz hat.

Mir ist allerdings auch noch nicht ganz klar, warum etwas, das technisch 
gesehen im Wesentlichen ein Append-Only-Log ohne Relationen und 
Transaktionen ist, und daher auch keine relationale oder transaktionale 
Integrität garantieren muß, unbedingt in einer relationalen Datenbank 
gespeichert werden muß. Sowas ist unnötig kompliziert und 
ressourcenaufwändig, das kann man besser machen, Stichworte: NoSQL, 
Columnar Store, ... aber leider scheint es für viele Entwickler und 
Architekten nur zwei Mechanismen zur Datenspeicherung zu geben, das 
Dateisystem oder ein klassisches relationales Datenbankmanagementsystem, 
üblicherweise mit SQL-Frontend. Dabei gibt es heute doch mit Tools 
CouchDB, MongoDB, Neo4j, Redis, Elasticsearch, Apache Solr, Splunk, 
Apache Cassandra, Prometheus, InfluxDB, Aerospike, ... so viele 
modernere Möglichkeiten, und die meisten haben Replikation und Sharding 
bereits eingebaut.

Mein persönlicher Favorit für Anwendungsfälle wie diesen ist 
Elasticsearch, das viel mehr als nur eine Volltext-Suchmaschine ist, und 
mit Kibana bereits ein Webfrontend für die interaktive Datenexploration, 
-Analyse und -Visualisierung bietet. Ich mag das Ding (trotz Java) sehr 
gerne, YMMV. Und, ach ja: wenn es wirklich ultraschnell, jedoch relativ 
einfach sein soll, könnte auch Redis eine gute Wahl sein...

von Ergo70 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bei XL und XC braucht es aber auch einen zentralen Koordinator, der die 
xids vergibt. Ist aber schon länger her, dass ich mir das mal angesehen 
habe. Da finde ich den Ansatz von Spanner deutlich interessanter. Wenn 
die Uhren nicht so teuer wären...

von Sheeva P. (sheevaplug)


Bewertung
0 lesenswert
nicht lesenswert
Ergo70 schrieb:
> Bei XL und XC braucht es aber auch einen zentralen Koordinator, der die
> xids vergibt.

Ja, richtig, aber bei den Genannten ist der Koordinator 
replikationsfähig. Das ist also NICHT die klassische HA, sondern echtes 
DC... ;-)

von Philipp K. (philipp_k59)


Bewertung
-2 lesenswert
nicht lesenswert
Das Problem löst doch die richtige query bzw. insert.

Ich würde das mit einem zusätzlichem Feld eindeutige zufällige union ID 
machen.. zB. "0xA56B1ADE554F48DAE55F26605AEA2E229D529BA2"

den Primärschlüssel verwaltet jeder Slave selbst und der Master hat nen 
Autoincrement bei Insert und produziert einen fehler beim insert einer 
gleichen union ID. So kann auch jeder Slave zurücksynchronisieren bzw. 
sogar untereinander synchen, die normale ID kann ja Links liegen 
gelassen werden.

von Bastler (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Das aller wichtigste bei Datenbanksachen: Sich niemals auf "externe" 
Primary-IDs verlassen. Das wird über kurz oder lang immer schief gehen. 
Irgendwelche IDs, Pointer, Kennungen etc. sind intern.

Eine andere wichtige Regel: Das Modell einer Datenbank, egal ob 
Relational, Hierarchisch, Objekt-orientiert oder Dokumeten-orientiert, 
sind nicht die Daten, sondern nur eine Abbildung der Daten.

Konkret für Deine Aufgaben: Was sind die Daten? Die Log-Einträge!

Ein Log-Eintrag besteht in Deiner Architektur aus:

  - System-Kennung
  - Zeitstempel
  - Meldung

Da kommt kein Primärschlüssel vor.

Dass Du in der SQL-Datenbank aus verschiedenen Gründen einen 
Primärschlüssel gerne hättest, ist den Daten egal. Das ist ein Detail 
Deiner gewählten Daten-Architektur. Also wäre ein einfache Architektur:

create table entries (id primary key autoincrement, systemId, timestamp, message);

Aber es wäre auch möglich, dass Du zwei Tabellen hast, eine für die 
eigenen Log-Enträge, diese Tabelle hätte keine System-ID, und eine für 
Fremdeinträge mit System-ID. Dann könntest Du auch einen View anlegen 
der die beiden Tabellen kombiniert, samt Trigger etc. Oder Du hast doch 
nur eine Tabelle und legst Dir einen View für Deine eigenen Einträge an. 
Aber das ist alles egal.

Die Synchronisierung ist von der Datenbank-Implementierung unabhängig: 
Jedes System kennt zu einer bestimmten System-ID den Eintrag mit dem 
neusten Zeitstempel. Danach können sich die System untereinander 
synchronisieren. Will man es robuster haben, kann man auch mit 
Sequenznummern arbeiten die man auch auf Lücken prüfen kann. Dann 
bestünde ein Log-Eintrag aus:

  - System-Kennung
  - Sequenz-Nummer
  - Zeitstempel
  - Meldung

Und noch ein Tipp: Die System-ID sollte nicht die IP-Adresse des Knoten 
sein, sondern eine feste Kennung, z.B. generiert aus einer Prozessor-ID, 
MAC-Adresse, o.ä.

von Bastler (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Also ein Log-Eintrag hat auf jedem System eine andere Primary-ID. Die 
Primary-ID wird nur intern verwendet und nicht zum Datenaustausch der 
Systeme untereinander.

von Ergo70 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hm, die XL Doku sagt: „Der globale Transaktionsmanager (GTM) kann einen 
GTM-Standby haben.„ Inwiefern ist das jetzt besser als z.B. mehrere 
repmgr? Abgesehen davon, das XL auch die Schreiblast verteilen kann. 
Aber das kann bucardo auch. Nicht so elegant, aber dafür muss man auch 
keine Interna  patchen. Selbst bei Citus finde ich einen zentralen 
Koordinator.

von Sheeva P. (sheevaplug)


Bewertung
0 lesenswert
nicht lesenswert
Ergo70 schrieb:
> Hm, die XL Doku sagt: „Der globale Transaktionsmanager (GTM) kann einen
> GTM-Standby haben.„ Inwiefern ist das jetzt besser als z.B. mehrere
> repmgr? Abgesehen davon, das XL auch die Schreiblast verteilen kann.
> Aber das kann bucardo auch. Nicht so elegant, aber dafür muss man auch
> keine Interna  patchen. Selbst bei Citus finde ich einen zentralen
> Koordinator.

repmgr und bucardo können AFAIK nur Replikation, aber kein Sharding. 
Horizontale Skalierbarkeit kannst Du damit also leider vergessen. Und ob 
in Perl entwickelte Software (bucardo) der Performance Deiner Datenbank 
zuträglich ist, wage ich als jemand, der viele Jahre lang Software in 
Perl entwickelt hat, zu bezweifeln. Das kannst Du machen, wenn Du viele 
Ressourcen und wenig Arbeit dafür hast, aber für hochperformante und 
-effiziente Setups wird das schwierig.

Citus dagegen spielt in einer anderen Liga und ähnelt Postgres-XL, ist 
allerdings meines Wissens eine kommerzielle Software, und scheint (!) 
mir seit der Übernahme durch Microsoft im Wesentlichen auf die 
Azure-Cloud ausgerichtet zu werden. Neben Citus hat Microsoft aber noch 
ein eigenes, durchaus brauchbares RDBMS im Angebot: nämlich den 
Microsoft SQL Server. Nach meiner Erfahrung mit derartigen Übernahmen 
beschleicht mich daher leider eine gewisse Skepsis für die 
Zukunftsfähigkeit...

Aber ja, Du hast Recht: wenn Performance keine große Rolle spielt (und 
auf kleinen Plattformen wie den RasPi ist das noch viel wichtiger), kann 
man mit allen diesen Ansätzen eine Replikation und mit Citus sogar 
Replikation und Sharding erreichen.

Aber das ändert ja am Ende nichts an meinem eigentlichen Argument, daß 
derartige Systeme für die Speicherung von Append-Only-Logs schlecht 
geeignet sind. Influx, Prometheus und Druid haben neben Replikation und 
Sharding viele Features, die es deutlich vereinfachen, Zeitseriendaten 
wie Append-Only-Logs zu verarbeiten.

Und wer sich nicht für jedes Fitzelchen Daten in eine neue Software 
einarbeiten möchte, der nimmt halt einen Allrounder wie Elasticsearch. 
Es hat sicherlich so seine guten Gründe, warum das als Datenbackend 
vieler Werkzeuge von Verinice -- einem Werkzeug des Bundesamtes für 
Sicherheit in der Informationstechnik, BSI -- sowie einem 
spezialisierten Log-Aggregator wie Graylog dient. Zudem hat es ein 
wunderbares Webfrontend, Kibana, für die Analyse und Visualisierung der 
Daten.

von Bauform B. (bauformb)


Bewertung
0 lesenswert
nicht lesenswert
Evt. solltet ihr euch zwischendurch an eine Randbedingung erinnern:

Alexander K. schrieb:
> auf mehreren Raspberry Pi's

die wahrscheinlich garkeinen lokalen Massenspeicher haben, außer ihrer 
SD-Karte, also keinen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.