Ich glaube nicht, dass es einen einfachen Weg gibt, der so einfach ist wie normale Sequenzen, weil:
- Eine Sequenz speichert nur einen Zahlenstrom (nächster Wert usw.). Sie möchten eine für jede Partition.
- Sequenzen haben eine spezielle Behandlung, die die aktuelle Transaktion umgeht (um die Race-Bedingung zu vermeiden). Es ist schwierig, dies auf SQL- oder PL/pgSQL-Ebene zu replizieren, ohne Tricks wie dblink zu verwenden.
- Die Spalteneigenschaft DEFAULT kann einen einfachen Ausdruck oder einen Funktionsaufruf wie
nextval('myseq')
verwenden; aber es kann nicht auf andere Spalten verweisen, um die Funktion darüber zu informieren, aus welchem Stream der Wert stammen soll.
Sie können etwas machen, das funktioniert, aber Sie werden es wahrscheinlich nicht für einfach halten. Behandeln der oben genannten Probleme der Reihe nach:
- Verwenden Sie eine Tabelle, um den nächsten Wert für alle Partitionen zu speichern, mit einem Schema wie
multiseq (partition_id, next_val)
. -
Schreiben Sie ein
multinextval(seq_table, partition_id)
Funktion, die etwa Folgendes tut:- Erstellen Sie eine neue Transaktion unabhängig von der aktuellen Transaktion (eine Möglichkeit, dies zu tun, ist über dblink; ich glaube, einige andere Serversprachen können dies einfacher).
- Sperre die in
seq_table
erwähnte Tabelle . - Aktualisieren Sie die Zeile, in der die Partitions-ID
partition_id
ist , mit einem inkrementierten Wert. (Oder fügen Sie eine neue Zeile mit dem Wert 2 ein, falls noch keine vorhanden ist.) - Commitieren Sie diese Transaktion und geben Sie die zuvor gespeicherte ID (oder 1) zurück.
-
Erstellen Sie einen Insert-Trigger für Ihre Projekttabelle, der einen Aufruf von
multinextval('projects_table', NEW.Project_ID)
verwendet für Einfügungen.
Ich habe diesen gesamten Plan nicht selbst verwendet, aber ich habe etwas Ähnliches für jeden Schritt einzeln ausprobiert. Beispiele für multinextval
Funktion und der Auslöser können bereitgestellt werden, wenn Sie dies versuchen möchten ...