Frage

Ich habe eine Postgres-Datenbank mit einem Benutzertabelle (Benutzer-ID, Vorname, Nachname) und eine usermetadata Tabelle (Benutzer-ID, Code, Inhalt, Datumzeit erstellt). Ich speichere verschiedene Informationen über jeden Benutzer in der usermetadata Tabelle von Code und halte eine vollständige Geschichte. so beispielsweise ein Benutzer (Benutzer-ID 15) die folgenden Metadaten:

15, 'QHS', '20', '2008-08-24 13:36:33.465567-04'  
15, 'QHE', '8', '2008-08-24 12:07:08.660519-04'  
15, 'QHS', '21', '2008-08-24 09:44:44.39354-04'  
15, 'QHE', '10', '2008-08-24 08:47:57.672058-04'  

Ich brauche eine Liste aller meiner Benutzer und den aktuellsten Wert von jeder der verschiedenen usermetadata Codes zu holen. Ich tat dies programmatisch und es war natürlich godawful langsam. Das Beste, was ich herausfinden konnte, es in SQL zu tun war, Unter wählt zu verbinden, die auch langsam waren und ich hatte eine für jeden Code zu tun.

War es hilfreich?

Lösung

Ich nehme an, Sie nicht bereit sind, Ihr Schema zu ändern, so fürchte ich meine answe keine große Hilfe sein könnte, aber hier geht ...

Eine mögliche Lösung wäre es, das Zeitfeld haben, leer, bis sie durch einen neuen Wert ersetzt, wenn Sie den ‚deprecation date‘ statt einfügen. Eine weitere Möglichkeit ist es, die Tabelle mit einer ‚aktiven‘ Spalte zu erweitern, aber das würde eine gewisse Redundanz einzuführen.

Die klassische Lösung wäre, beides zu haben ‚Gültig-ab‘ und ‚Gültig-To‘ Bereiche, in denen die ‚Gültig-To‘ Felder leer sind, bis ein anderer Eintrag gültig wird. Dies kann durch Verwendung Trigger oder ähnlich leicht zu handhaben sein. Mit Einschränkungen, um sicherzustellen, gibt es nur ein Element eines jeden Typs ist, der gültig ist, wird die Datenintegrität gewährleisten.

gemein davon ist, dass es eine einzige Art und Weise, die Gesamtheit der Stromfelder zu bestimmen. Sie würden einfach alle Einträge mit dem aktiven Benutzer auswählen und ein NULL ‚Gültig-To‘ oder ‚deprecation Datum‘ oder einem echten ‚aktiv‘.

Sie können in einen Blick auf die Wikipedia-Eintrag interessiert sein an temporalen Datenbanken und die Artikel ein Konsens Glossar der zeitlichen Datenbankkonzepte .

Andere Tipps

Dies ist eigentlich nicht so schwer in PostgreSQL zu tun, weil es die "DISTINCT ON" Klausel in seiner SELECT-Syntax (DISTINCT ON ist nicht Standard-SQL).

SELECT DISTINCT ON (code) code, content, createtime
FROM metatable
WHERE userid = 15
ORDER BY code, createtime DESC;

Das wird die zurückgegebenen Ergebnisse an das erste Ergebnis pro eindeutigen Code begrenzen, und wenn Sie die Ergebnisse durch die Erstellungszeit absteigend sortieren, werden Sie die neueste jeder bekommen.

Ein subselect ist der normale Weg, diese Art der Sache zu tun. Sie brauchen nur eine einzigartige Constraint auf Benutzer-ID, Code und Datum - und dann können Sie die folgenden ausführen:

SELECT * 
FROM Table
JOIN (
   SELECT UserId, Code, MAX(Date) as LastDate
   FROM Table
   GROUP BY UserId, Code
) as Latest ON
   Table.UserId = Latest.UserId
   AND Table.Code = Latest.Code
   AND Table.Date = Latest.Date
WHERE
   UserId = @userId
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top