Metadaten für einzelne Datensätze

Tom.S

Fleissiger Benutzer
Beiträge
62
Hallo,
ich suche nach einer geeigneten Möglichkeit, einzelne Datensätze mit zusätzlichen Daten anzureichern.
Beispielsweise habe ich eine Tabelle 'Firmenwagen'

ID | Fahrer | Auto
1 | Meier | Porsche
2 | Müller | Jaguar
...

und möchte folgendes erreichen:

ID | Fahrer | Auto | eingetragen von | eingetragen am |
1 | Meier | Porsche | A. D. | 03.02.2015
2 | Müller | Jaguar | C. W. | 06.03.2015
...

Das Problem an diesem naiven Ansatz:
1) Ich habe hunderte Tabellen. Möchte ich wissen, wer als letzter etwas eingetragen hat, muss ich die Daten aus allen Tabellen auslesen.
2) Es vermischt die Ebenen: Die konkreten Daten werden mit administrativen Daten verknüpft.

Als Lösung sehe ich eigentlich nur eine große Tabelle "Eintragungen" mit einer Referenz auf die Datensätze. Mein Problem ist jetzt aber das Aussehen der Referenz: Korrekt wäre wohl eine große Tabelle zu erstellen und dann eine Kopplungstabelle für jede Tabelle zu erstellen. Das würde zwar die Daten sauber trennen, meine Tabellenzahl aber auf einen Schlag verdoppeln.
Die etwas unsaubere, aber weit praktikablere, Lösung aus meiner Sicht wäre eine Tabelle mit folgender Struktur:

ID | referenzierte_tabelle | id (referenzierte_tabelle) | eingetragen von | eingetragen am |
79 | Firmenwagen | 2 | C. W. | 06.03.2015

Jetzt würde ich gerne wissen, ob das so sinnvoll ist oder ob es noch eine bessere Lösung gibt. Und ich würde gerne wissen, wie man die Tabelle in PostgreSQL sinnvoll referenziert. Muss man den Tabellennamen nehmen oder gibt es eine PostgreSQL-interne Tabellen-ID, die auch nach einer Umbenennung der Tabelle erhalten bleibt?
 
Werbung:
Hallo,
ich suche nach einer geeigneten Möglichkeit, einzelne Datensätze mit zusätzlichen Daten anzureichern.
Beispielsweise habe ich eine Tabelle 'Firmenwagen'

ID | Fahrer | Auto
1 | Meier | Porsche
2 | Müller | Jaguar
...

und möchte folgendes erreichen:

ID | Fahrer | Auto | eingetragen von | eingetragen am |
1 | Meier | Porsche | A. D. | 03.02.2015
2 | Müller | Jaguar | C. W. | 06.03.2015
...

Das Problem an diesem naiven Ansatz:

Das ist aber eigentlich so ganz okay. Aber sehen wir mal weiter...

1) Ich habe hunderte Tabellen. Möchte ich wissen, wer als letzter etwas eingetragen hat, muss ich die Daten aus allen Tabellen auslesen.
2) Es vermischt die Ebenen: Die konkreten Daten werden mit administrativen Daten verknüpft.

Ist das jetzt praxisrelevant, daß Du wissen willst, wer als letztes in einer beliebigen Tabelle was eingetragen hat? Das erscheint mir jetzt, ehrlich gesagt, recht an den Haaren herbeigezogen.


Als Lösung sehe ich eigentlich nur eine große Tabelle "Eintragungen" mit einer Referenz auf die Datensätze. Mein Problem ist jetzt aber das Aussehen der Referenz: Korrekt wäre wohl eine große Tabelle zu erstellen und dann eine Kopplungstabelle für jede Tabelle zu erstellen. Das würde zwar die Daten sauber trennen, meine Tabellenzahl aber auf einen Schlag verdoppeln.
Die etwas unsaubere, aber weit praktikablere, Lösung aus meiner Sicht wäre eine Tabelle mit folgender Struktur:

ID | referenzierte_tabelle | id (referenzierte_tabelle) | eingetragen von | eingetragen am |
79 | Firmenwagen | 2 | C. W. | 06.03.2015

Jetzt würde ich gerne wissen, ob das so sinnvoll ist oder ob es noch eine bessere Lösung gibt. Und ich würde gerne wissen, wie man die Tabelle in PostgreSQL sinnvoll referenziert. Muss man den Tabellennamen nehmen oder gibt es eine PostgreSQL-interne Tabellen-ID, die auch nach einer Umbenennung der Tabelle erhalten bleibt?

Es gibt sowas, die OID. Die kannst Du für jedes Objekt aus der pg_class Dir holen. Ich würde aber eher abraten, in User-Tabellen mit internen OID's zu arbeiten. Das fällt Dir spätestens dann auf die Füße, wenn Du einen Dump machst und diesen in einer anderen Umgebung (andere Version, andere schon vorhandenen Daten etc.) wieder einspielen willst. Don't do that!

Um noch mal auf Deine erste Idee zu kommen: was spricht gegen einen TRIGGER, der in den relevanten Tabellen bei Insert/Update den Timestamp und den current_user einträgt?

Oder aber einen Trigger auf den relevanten Tabellen, der ein zentrales Log führt. Hier noch eine fertige Lösung:

http://andreas.scherbaum.la/blog/archives/100-Log-Table-Changes-in-PostgreSQL-with-tablelog.html

Beachte dort auch den Kommentar #12 (von mir), der eine auch sehr nette und modernere/flexiblere Lösung als die von ads zeigt.
 
Hallo,
ich suche nach einer geeigneten Möglichkeit, einzelne Datensätze mit zusätzlichen Daten anzureichern.
Beispielsweise habe ich eine Tabelle 'Firmenwagen'

ID | Fahrer | Auto
1 | Meier | Porsche
2 | Müller | Jaguar
...

und möchte folgendes erreichen:

ID | Fahrer | Auto | eingetragen von | eingetragen am |
1 | Meier | Porsche | A. D. | 03.02.2015
2 | Müller | Jaguar | C. W. | 06.03.2015
Und was hindert dich jetzt daran deiner Tabelle "Firmenwagen" zwei Spalten "modified_date" und "modified_from" anzuhängen?

Das Problem an diesem naiven Ansatz:
1) Ich habe hunderte Tabellen. Möchte ich wissen, wer als letzter etwas eingetragen hat, muss ich die Daten aus allen Tabellen auslesen.
2) Es vermischt die Ebenen: Die konkreten Daten werden mit administrativen Daten verknüpft.
Zu 1: Wenn du wirklich so viele Tabellen hast... Ist die Aussage "Das ist der letzte User der IRGENDWO in der Datenbank etwas geändert hat" sowieso nicht möglich... Da es wahrscheinlich sekündlich ein neuer User sein wird... Es sei denn du brauchst diese Information wirklich nur ein paar Millisekunden...
Zu 2: Das verstehe ich jetzt nicht... Wo ist denn da das Problem?
Jetzt würde ich gerne wissen, ob das so sinnvoll ist oder ob es noch eine bessere Lösung gibt.
Möglich? Ja... Sinnvoll ? Nein... Nach einer Woche ist deine Datenbank auf "mysteriöse Art und weise" auf die doppelte Größe herangewachsen... Weil wirklich jede Änderung mitgeschrieben wird und du für jede Änderung auch einen neuen Datensatz anlegt... Und da du nur sehr kostenintensiv entscheiden kannst welcher Datensatz gelöscht werden kann... Gibt es auch nur bedingte bis keine Möglichkeiten diese Tabelle in einer angemessenen Größe zu halten ohne Performance einbußen...


Hängt natürlich auch davon ab, wieviele Datensätze deine Tabellen halten und wieviele User du hast...
 
Werbung:
Zu 1: Wenn du wirklich so viele Tabellen hast... Ist die Aussage "Das ist der letzte User der IRGENDWO in der Datenbank etwas geändert hat" sowieso nicht möglich... Da es wahrscheinlich sekündlich ein neuer User sein wird... Es sei denn du brauchst diese Information wirklich nur ein paar Millisekunden...

Möglich? Ja... Sinnvoll ? Nein... Nach einer Woche ist deine Datenbank auf "mysteriöse Art und weise" auf die doppelte Größe herangewachsen... Weil wirklich jede Änderung mitgeschrieben wird und du für jede Änderung auch einen neuen Datensatz anlegt... Und da du nur sehr kostenintensiv entscheiden kannst welcher Datensatz gelöscht werden kann... Gibt es auch nur bedingte bis keine Möglichkeiten diese Tabelle in einer angemessenen Größe zu halten ohne Performance einbußen...
Hallo Distrilec,
es handelt sich um eine Datenbank, mit maximal 20 Benutzern, die alle paar Tage mal etwas eintragen.
Die Größe der Datenbank ist also sehr begrenzt. Zentral ist aber eine Verifizierbarkeit der Daten und dazu zählen halt solche Metadaten für einen Eintrag.

Es gibt sowas, die OID. Die kannst Du für jedes Objekt aus der pg_class Dir holen. Ich würde aber eher abraten, in User-Tabellen mit internen OID's zu arbeiten.
Hallo akretschmer,
ja, war auch mein erster Gedanke. Sie sind zudem inzwischen auch als Depraced gekennzeichnet und scheiden auch deshalb als Möglichkeit aus.

Um noch mal auf Deine erste Idee zu kommen: was spricht gegen einen TRIGGER, der in den relevanten Tabellen bei Insert/Update den Timestamp und den current_user einträgt?
Mist, ich sollte meine Beispiele nicht immer so verkürzen: Es sollen nicht nur User und Timestamp eingetragen werden, sondern der User soll auch einen Kommentar zu dem Eintrag verfassen können. Deshalb fielen Trigger als Möglichkeit weg.

Auch wenn mir da das Informatikerherz blutet, schaue ich mir die Möglichkeit, die Metadatenattribute einfach an jede Tabelle zu hängen mal näher an, wenn Ihr das auch so machen würdet.
Danke für die Antworten.
 
Zurück
Oben