Ich will Veränderungen am Datenbestand speichern. Die Idee ist, eine Tabelle mit zwei Schlüsseln zu machen. Der Primärschlüssel (sn
) identifiziert alle aktuellen und historischen Zeilen der Tabelle. Und ein weiter Schlüssel (id
) identifiziert nur die Person unabhängig von den Veränderungen ihrer Attribute. Dazu habe ich einen Zeitstempel für die Modifikation erstellt. Wann immer der Zeitstempel NULL ist, wurde keine Modifikation vorgenommen, es ist also der aktuell Wert.
DROP TABLE IF EXISTS person;
CREATE TABLE person (
sn serial PRIMARY KEY,
id int NOT NULL,
modified timestamp,
name text
);
CREATE UNIQUE INDEX version_id_key ON version (id) WHERE modified IS NULL;
DROP TABLE IF EXISTS account;
CREATE TABLE account (
id int NOT NULL REFERENCES person(id),
name text
);
Leider funktioniert der Fremdschlüssel nicht. Ziel war es, dass die Konten nur auf die Identität der Person verweisen und nicht auf eine konkrete historische Ausprägung. Das Beispiel schmeißt den Fehler:
ERROR: there is no unique constraint matching given keys for referenced table “person”
Was ist nicht verstehe ist, warum es angeblich keinen Index gäbe, obwohl der UNIQUE-Index auf id
angezeigt wird:
Table "public.person"
Column | Type | Collation | Nullable | Default
----------+-----------------------------+-----------+----------+------------------------------------
sn | integer | | not null | nextval('person_sn_seq'::regclass)
id | integer | | not null |
modified | timestamp without time zone | | |
name | text | | |
Indexes:
"person_pkey" PRIMARY KEY, btree (sn)
"person_id_key" UNIQUE, btree (id) WHERE modified IS NULL
Was stimmt nicht mit dem Index?
Ja ich weiß, ich könnte zwei Tabellen pro Entität machen: eine für die veränderlichen und eine für die unveränderlichen Daten. Aber ich würde es gerne mit einer Tabelle lösen.