PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Dodaj ograniczenie, aby kolumna była unikalna dla grupy wierszy

Jak @lad2025 skomentował , status naprawdę powinno być boolean . Tańsze, czystsze.

Tak czy inaczej, możesz narzucić swoją regułę za pomocą częściowego unikalnego indeksu :

Aby zezwolić na zero lub jeden wiersz ze status = 'Active' w całej tabeli :

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

Aby zezwolić na zero lub jeden wiersz ze status = 'Active' na userid , utwórz userid indeksowana kolumna:

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

Zauważ, że userid IS NULL nie wywoła unikalnych naruszeń, ponieważ dwie wartości NULL nigdy nie są uważane za równe. userid należy ustawić NOT NULL w tym przypadku.

Dlaczego indeks, a nie ograniczenie?

Zajęcie się pytanie w komentarzu :To jest indeks, a nie CONSTRAINT .

Indeks dla pierwszego przypadku jest malutki , trzymając jeden wiersz lub nie.
Indeks dla drugiego przypadku zawiera jeden wiersz na istniejący userid , ale jest to najtańszy i najszybszy sposób , oprócz tego, że jest czysty i bezpieczny. Aby to przyspieszyć, w każdym przypadku potrzebny byłby indeks do sprawdzania innych wierszy.

Nie możesz mieć CHECK sprawdzanie ograniczeń w innych wierszach - przynajmniej nie w czysty, niezawodny sposób. Są sposoby, których z pewnością nie polecam w tym przypadku:

Jeśli używasz UNIQUE ograniczenie na (userid, status) (co jest również zaimplementowane z unikalnym indeksem w tle!), nie można uczynić go częściowym i wszystkie kombinacje są wymuszane, aby były niepowtarzalne. możesz nadal używaj tego, jeśli pracujesz ze status IS NULL we wszystkich przypadkach z wyjątkiem 'Active' walizka. Ale w rzeczywistości narzuciłoby to znacznie większy indeks, w tym wszystkie wiersze.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. postgresql:INSERT INTO ... (WYBIERZ * ...)

  2. Pobierz nazwę dnia z daty w PostgreSQL

  3. Jak Cos() działa w PostgreSQL

  4. Transpozycja wyniku sql, tak aby jedna kolumna przechodziła do wielu kolumn

  5. jak zapytać o min lub max inet/cidr za pomocą postgres