2013-04-26 14 views
50

Ich möchte eine Einschränkung hinzufügen, die Eindeutigkeit für eine Spalte nur in einem Teil einer Tabelle erzwingt.Postgresql: Bedingte eindeutige Einschränkung

ALTER TABLE stop ADD CONSTRAINT myc UNIQUE (col_a) WHERE (col_b is null); 

Der WHERE Teil oben ist Wunschdenken.

Jeder Weg, dies zu tun? Oder sollte ich zurück zum relationalen Zeichenbrett gehen?

+0

Dies wurde bereits hier beantwortet: http://stackoverflow.com/questions/469471/how-do-i-alter-a-postgresql-table-and-make-a-column- einzigartig – yvesonline

+2

Häufig gemacht. Siehe "teilweise eindeutiger Index" –

+10

@yvesonline nein, das ist eine reguläre eindeutige Einschränkung. Das Poster möchte eine * partielle * eindeutige Einschränkung. –

Antwort

92

PostgreSQL nicht eine partielle (dh bedingte) UNIQUE Einschränkung definieren - aber Sie können einen Teil Index einzigartig erstellen. PostgreSQL verwendet eindeutige Indizes, um eindeutige Constraints zu implementieren, so dass der Effekt derselbe ist. Sie werden das Constaint einfach nicht in information_schema aufgelistet finden.

CREATE UNIQUE INDEX stop_myc ON stop (col_a) WHERE (col_b is null); 

Siehe partial indexes.

+13

Super! Nicht intuitiv, dass die "Einschränkung" nicht als Einschränkung angezeigt wird, aber dennoch den gewünschten Fehler von FEHLER gibt: doppelter Schlüsselwert verletzt eindeutige Einschränkung "stop_myc" – EoghanM

+2

Es ist erwähnenswert, dass dies die Erstellung von FKs referencig nicht erlaubt das teilweise eindeutige Feld. – amenadiel

1

Es wurde bereits gesagt, dass PG keine partielle (dh bedingte) UNIQUE-Einschränkung definiert. Auch sagt Dokumentation, dass der bevorzugte Weg, um eine eindeutige Einschränkung auf eine Tabelle hinzuzufügen, ist ADD CONSTRAINTUnique Indexes

The preferred way to add a unique constraint to a table is ALTER TABLE ... ADD CONSTRAINT. The use of indexes to enforce unique constraints could be considered an implementation detail that should not be accessed directly. One should, however, be aware that there's no need to manually create indexes on unique columns; doing so would just duplicate the automatically-created index.

Es gibt einen Weg, es zu implementieren ist Exclusion Constraints Verwendung

In Ihrem Fall (@dukelion für diese Lösung danken) es wie

ALTER TABLE stop 
    ADD CONSTRAINT stop_col_a_key_part EXCLUDE (col_a WITH =) WHERE (col_b IS null); 
aussehen
+0

auf diesem Ansatz verwenden Sie nicht "verwenden", um Index-Methode zu definieren, so dass kann sehr langsam oder Postgres erstellt einen Standard-Index auf das? Diese Methode ist die kanonische Wahl, aber nicht immer die bessere Wahl! Ich denke, dass Sie eine "using" -Klausel mit Index benötigen, um diese Wahl die bessere zu machen. –

Verwandte Themen