sql >> Database teknologi >  >> RDS >> PostgreSQL

Tilføj begrænsning for at gøre kolonne unik pr. gruppe af rækker

Synes godt om @20 /a> , status burde virkelig være boolean . Billigere, renere.

Uanset hvad, kan du indføre din regel med et delvist unikt indeks :

At tillade nul eller én række med status = 'Active' i hele tabellen :

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

At tillade nul eller én række med status = 'Active' pr. userid , lav userid den indekserede kolonne:

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

Bemærk, at userid IS NULL ville ikke udløse unikke overtrædelser, fordi to NULL-værdier aldrig betragtes som ens. userid skal være sat NOT NULL i dette tilfælde.

Hvorfor indeksere og ikke begrænsning?

Adressering af din CONSTRAINT .

Indekset for det første tilfælde er lille , holder en eller ingen række.
Indekset for det andet tilfælde indeholder en række pr. eksisterende userid , men det er den billigste og hurtigste måde , ud over at være rent og sikkert. Du skal under alle omstændigheder have et indeks for at kontrollere andre rækker for at gøre dette hurtigt.

Du kan ikke have en CHECK begrænsningskontrol på andre rækker - i hvert fald ikke på en ren, pålidelig måde. Der er måder, jeg bestemt ikke vil anbefale for dette tilfælde:

Hvis du bruger en UNIQUE begrænsning på (userid, status) (som også er implementeret med et unikt indeks i baggrunden!), du kan ikke gøre det delvis , og alle kombinationer tvinges til at være unikke. Du kunne brug stadig dette, hvis du arbejder med status IS NULL for alle tilfælde undtagen 'Active' sag. Men det ville faktisk påtvinge et meget større indeks inklusive alle rækker.




  1. PostgreSQL drop-rolle mislykkes på grund af standardprivilegier

  2. ORA-01843:ikke en gyldig måned, når du indsætter en dato i oracle

  3. Hvordan bruger jeg LINQ korrekt med MySQL?

  4. Sådan gemmer du billede i kolonnen SQL Server-databasetabeller