PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Erstellen Sie eine eindeutige Einschränkung mit Nullspalten

Erstellen Sie zwei Teilindizes :

CREATE UNIQUE INDEX favo_3col_uni_idx ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;

CREATE UNIQUE INDEX favo_2col_uni_idx ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;

Auf diese Weise kann es nur eine Kombination von (user_id, recipe_id) geben wobei menu_id IS NULL , wodurch die gewünschte Einschränkung effektiv implementiert wird.

Mögliche Nachteile:

  • Sie können keinen Fremdschlüssel haben, der auf (user_id, menu_id, recipe_id) verweist . (Es scheint unwahrscheinlich, dass Sie eine FK-Referenz drei Spalten breit haben möchten - verwenden Sie stattdessen die PK-Spalte!)
  • Sie können CLUSTER nicht als Basis verwenden auf einem Teilindex.
  • Abfragen ohne passenden WHERE Bedingung kann den partiellen Index nicht verwenden.

Wenn Sie eine vollständige benötigen index können Sie alternativ das WHERE löschen Bedingung aus favo_3col_uni_idx und Ihre Anforderungen werden weiterhin durchgesetzt.
Der Index, der jetzt die gesamte Tabelle umfasst, überschneidet sich mit dem anderen und wird größer. Abhängig von typischen Abfragen und dem Prozentsatz von NULL Werte, kann dies nützlich sein oder auch nicht. In Extremsituationen kann es sogar helfen, alle drei Indizes zu pflegen (die beiden partiellen und die Summe oben).

Dies ist eine gute Lösung für eine einzelne Nullable-Spalte , vielleicht für zwei. Aber für mehr gerät es schnell aus den Händen, da Sie für jede Kombination von Nullable-Spalten einen separaten Teilindex benötigen, sodass die Zahl binomial wächst. Für mehrere Nullable-Spalten , siehe stattdessen:

  • Warum wird meine UNIQUE-Einschränkung nicht ausgelöst?

Übrigens:Ich rate davon ab, Groß- und Kleinschreibung in PostgreSQL zu verwenden.