Aktiver Datensatz?

Hallo,

bin gerade am Lernen von PostgreSQL und Datenbanken im Allgemeinen und will zunächst ein Tabelle “Benutzer” mit mehreren Personen (Tulips) erstellen. Nach einem Neustart des Computers möchte ich schauen, welcher Benutzer zuletzt aktiv war. Wie erstellt man am besten so eine Tabelle?
Kann man in PostgreSQL einen Datensatz "aktivieren2? Oder bräuchte man eine zusätzliche Spalte, beispielsweise “aktiver Benutzer”, wo man nach dem Neustart nachschauen könnte. Könnte man auch sicherstellen, dass immer nur ein Benutzer aktiv wäre?

Herzlichen Dank für eure Tipps?

Kalle

Du suchst offenbar einen partiellen unique Index:

test=# create table benutzer (name text, aktiv bool);
CREATE TABLE
Time: 238,852 ms
test=*# create unique index on benutzer(aktiv) where aktiv is true;
CREATE INDEX
Time: 36,406 ms
test=*# insert into benutzer values ('name1', false);
INSERT 0 1
Time: 0,447 ms
test=*# insert into benutzer values ('name2', false);
INSERT 0 1
Time: 0,179 ms
test=*# insert into benutzer values ('name3', false);
INSERT 0 1
Time: 0,147 ms
test=*# insert into benutzer values ('name4', true);
INSERT 0 1
Time: 0,400 ms
test=*# insert into benutzer values ('name5', true);
ERROR:  duplicate key value violates unique constraint "benutzer_aktiv_idx"
DETAIL:  Key (aktiv)=(t) already exists.
Time: 0,265 ms

Es kann also nur einer ‘aktiv’ sein.


Andreas

Ja, das ist was, was ich mir beim Einstieg in pSQL (sql generell) auch wieder klarmachen musste: SQL ist - wie der Name sagt - eine Abfragesprache. D.h., wenn Du es nicht selbst in Deiner Anwendung sicherst, gibt es keinen aktuellen Datensatzpuffer (wie z.B. in DataFlex o.ä.) und keine “zuletzt”-Werte. Ist in der Logik des Datenbank-Server-Konzeptes begründet.
Die Methode, PSQL einen Fehler aufgrund eines unique index produzieren zu lassen, um mehrfaches “aktiv”-Sein auszuschließen, halte ich allerdings - bei allem Respekt für Andreas und seine großen Kenntnisse - für die ultima ratio, die ich nur gezwungenermaßen (armselige Anwendung) wählen würde bzw. zusätzlich zu einem anständigen Login/Logout.
Der normale Vorgang wäre doch, dass die Anwendung, z.B. php abfragt, ob da schon wer aktiv ist, wenn ja, abweist und wenn nein, einen neuen aktiven einträgt (und bei Abmeldung oder Verbindungsabbruch auch wieder austrägt)…

Ok, ich habe soweit verstanden, was ich machen muss :wink:

Danke für eure Antworten!

Kalle

Das eine schließt doch das andere nicht aus. Die Anwendung smart genug machen, daß es nicht passiert, und die DB drüber wachen lassen - als extra Schutz. Die DB kann das sehr wahrscheinlich einfacher als die Applikation. Dazu kommen noch diverse Probleme durch mehrfachen Zugriff in PHP.

Andreas

Nein, solche Checks gehören immer in die Datenbank.

Es ist sehr wahrscheinlich, dass langfristig mehr als eine Anwendung auf diese Daten zugreift. Meistens leben die Daten(banken) auch länger als die Anwendungen und letztlich schliesst man damit auch Benutzerfehler aus (Installationsskripte die einen Fehler enthalten, ein Benutzer der ein Script aus Versehen zweimal laufen lässt usw).

Ob man in der Anwendung noch zusätzliche Prüfungen einbaut ist davon unabhängig. Meistens wird man das machen, um z.B. alle Felder eines Formulars auf einmal zu prüfen und nicht den Anwender 20 mal einen Fehler anzuzeigen - aber das ist “optional”.

Die Prüfung in der Datenbank ist auf keine Fall optional - die ist ein “Muss”

Einen Datensatz ‘aktivieren’ geht in einer Datenbank so nicht, das wäre Aufgabe einer Applikation, z.B. könnte man in der Anwendung einen Cursor erstellen, der die zu bearbeitenden Daten enthält und verwaltet.
Um festzustellen wer z.B. als letzter an einem Datensatz gearbeitet hat, bietet sich das mitführen von Feldern für Bearbeiter und letzte Änderung, die mit current_user und current_timestamp in einem Trigger beschrieben werden können. Damit kann in der Anwendung auch ein sog. optimistic locking realisiert werden, das konkurrierende Zugriffe verhindern hilft.

Gruß Uwe

Gruß Uwe

Hallo zusammen,

herzlichen Dank für die Tipps. Ich werde jetzt so umsetzen wie ihr es vorgeschlagen habt :wink:

Gruß

Kalle