Benutzerdefinierte eindeutige Spalteneinschränkung, nur erzwungen, wenn eine Spalte einen bestimmten Wert hat

19

Ist es möglich, eine benutzerdefinierte eindeutige Spalteneinschränkung wie folgt festzulegen? Angenommen, ich habe zwei Spalten subsetund typebeide Zeichenfolgen (obwohl die Datentypen wahrscheinlich keine Rolle spielen).

Wenn type"wahr" ist, dann möchte ich die Kombination von typeund subseteinzigartig sein. Ansonsten gibt es keine Einschränkung. Ich benutze PostgreSQL 8.4 unter Debian.

Faheem Mitha
quelle

Antworten:

31

Mit anderen Worten, Sie möchten subseteindeutig sein, wenn type = 'true'.
Ein partieller eindeutiger Index wird dies tun:

CREATE UNIQUE INDEX tbl_some_name_idx ON tbl (subset) WHERE type = 'true';

Auf diese Weise können Sie sogar Kombinationen mit NULLunique erstellen, was ansonsten nicht möglich ist - wie in dieser verwandten Antwort beschrieben:
PostgreSQL-Mehrspalten-Unique-Constraint und NULL-Werte

Erwin Brandstetter
quelle
Danke Erwin. Ich habe diese Option nicht gesehen, als ich mir die Dokumentation angesehen habe. Ein direkterer Link ist postgresql.org/docs/current/interactive/indexes-partial.html . Siehe Beispiel 11-3.
Faheem Mitha
@FaheemMitha: Ich verknüpft eine Ebene höher, da Sie benötigen kombinieren einen Teilindex mit einem eindeutigen Index .
Erwin Brandstetter
1
@Erwin Diese Seite (über Teilindizes) enthält ein Beispiel mit einem teilweise eindeutigen Index.
Ypercubeᵀᴹ
@ypercube: Ah, richtig. Das ist die bessere Verbindung. Ich habe meine Antwort geändert, um auf das letzte Kapitel zu verweisen.
Erwin Brandstetter
6

Dies ist eine Ergänzung zu Erwins Antwort oben, aber PostgreSQL unterstützt eine Reihe von Indextypen. Diese schließen sich in der Regel nicht aus. Sie können sich das vorstellen als:

  • Indexmethode (btree, GiST, GIN usw.). Wählen Sie bei Bedarf einen aus (Btree ist die Standardeinstellung)
  • Teilweise oder vollständig. Wenn teilweise, verwenden Sie eine where-Klausel
  • Direkt oder funktional. Sie können die Ausgabe von Funktionen indizieren.
  • Einzigartig oder nicht einzigartig

All dies kann auf verschiedene Arten kombiniert werden. Alles, was Sie hier tun, ist die Verwendung der eindeutigen und partiellen Funktionen, sodass Sie partielle eindeutige Indizes erhalten (die, wie Sie herausfinden, äußerst nützlich sind.

Angenommen, Sie möchten für das Teilmengenfeld einen Index ohne Berücksichtigung der Groß- und Kleinschreibung verwenden , bei dem der Typ wahr ist. Dann würden Sie eine funktionale Definition hinzufügen:

CREATE INDEX my_index_name_idx_u ON tbl (lower(subset)) WHERE type;

Beachten Sie, dass dadurch ein eindeutiger Index für die Ausgabe der Funktion lower () erstellt wird, die für das Attribut subset aufgerufen wird, bei dem type true ist.

Chris Travers
quelle
Der Index in Erwins Antwort ist also direkt, wohingegen der in Ihrem Beispiel in funktional korrekt ist?
Faheem Mitha
@FaheemMitha: Richtig.
Erwin Brandstetter