sql >> Databasteknik >  >> RDS >> PostgreSQL

Lägg till begränsning för att göra kolumnen unik per grupp av rader

Gilla @ladd /a> , status borde verkligen vara boolean . Billigare, renare.

Hur som helst kan du införa din regel med ett partiellt unikt index :

För att tillåta noll eller en rad med status = 'Active' i hela tabellen :

CREATE UNIQUE INDEX tbl_active_uni ON tbl (status)
WHERE status = 'Active';

För att tillåta noll eller en rad med status = 'Active' per userid , gör userid den indexerade kolumnen:

CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid)
WHERE status = 'Active';

Observera att userid IS NULL skulle inte utlösa unika överträdelser, eftersom två NULL-värden aldrig anses vara lika. userid måste ställas in NOT NULL i det här fallet.

Varför indexera och inte begränsa?

Adressera din CONSTRAINT .

Indexet för det första fallet är litet , med en eller ingen rad.
Indexet för det andra fallet innehåller en rad per befintligt userid , men det är det billigaste och snabbaste sättet , förutom att vara ren och säker. Du skulle behöva ett index för att kontrollera andra rader i alla fall för att göra detta snabbt.

Du kan inte ha en CHECK begränsningskontroll på andra rader - åtminstone inte på ett rent och tillförlitligt sätt. Det finns sätt jag absolut inte skulle rekommendera för det här fallet:

Om du använder en UNIQUE begränsning på (userid, status) (som också är implementerat med ett unikt index i bakgrunden!), du kan inte göra det partiellt och alla kombinationer tvingas vara unika. Du kunde använd fortfarande detta om du arbetar med status IS NULL för alla fall utom 'Active' fall. Men det skulle faktiskt påtvinga ett mycket större index inklusive alla rader.




  1. MySQL ERROR 1290 (HY000) --secure-file-priv option

  2. Välj produkter efter flera attribut, använd AND istället ELLER sammanlänkning, Datamodell EAV

  3. Doctrine Query Language få max/senaste raden per grupp

  4. Oracle-sekvens men då i MS SQL Server