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

Złożony klucz podstawowy wymusza ograniczenia NOT NULL na zaangażowanych kolumnach

Jeśli potrzebujesz aby zezwolić na wartości NULL, użyj UNIQUE ograniczenie zamiast PRIMARY KEY (i dodaj zastępczą kolumnę PK, proponuję serial ). Dzięki temu kolumny mogą mieć wartość NULL:

CREATE TABLE distributor (
   distributor_id serial PRIMARY KEY
 , m_id integer
 , x_id integer
 , UNIQUE(m_id, x_id)
);

Uwaga , jednak (zgodnie z dokumentacją):

Na potrzeby ograniczenia unikatowego wartości null nie są uważane za równe.

W twoim przypadku możesz wpisać coś takiego jak (1, NULL) dla (m_id, x_id) dowolną liczbę razy bez naruszania ograniczenia. Postgres nigdy nie uważa dwóch wartości NULL równych - zgodnie z definicją w standardzie SQL.

Jeśli musisz leczyć NULL wartości równe uniemożliwiające takie „duplikaty”, Widzę dwie opcje :

1. Dwa indeksy częściowe

Dodatkowo do UNIQUE ograniczenie powyżej:

CREATE UNIQUE INDEX dist_m_uni_idx ON distributor (m_id) WHERE x_id IS NULL;
CREATE UNIQUE INDEX dist_x_uni_idx ON distributor (x_id) WHERE m_id IS NULL;

Ale to szybko wymyka się z rąk, gdy więcej niż dwie kolumny mogą mieć wartość NULL. Zobacz:

  • Utwórz unikalne ograniczenie z pustymi kolumnami

2. Wielokolumnowy UNIQUE indeks wyrażeń

Zamiast ograniczenia UNIQUE. Potrzebujemy darmowej wartości domyślnej, która nigdy nie występuje w zaangażowanych kolumnach, np. -1 . Dodaj CHECK ograniczenia uniemożliwiające to:

CREATE TABLE distributor (
   distributor serial PRIMARY KEY
 , m_id integer
 , x_id integer
 , CHECK (m_id &lt> -1)
 , CHECK (x_id &lt> -1)
);
CREATE UNIQUE INDEX distributor_uni_idx ON distributor (COALESCE(m_id, -1)
                                                      , COALESCE(x_id, -1))

Jak niektóre RDBMS radzą sobie z różnymi sprawami nie zawsze jest użytecznym wskaźnikiem prawidłowego zachowania. Instrukcja obsługi Postgresa podpowiada to:

Oznacza to, że nawet w obecności unikatowego ograniczenia możliwe jest przechowywanie zduplikowanych wierszy zawierających wartość null w co najmniej jednej z ograniczonych kolumn. To zachowanie jest zgodne ze standardem SQL, ale słyszeliśmy, że inne bazy danych SQL mogą nie przestrzegać tej zasady .Więc zachowaj ostrożność podczas tworzenia aplikacji, które mają być przenośne.

Pogrubiony nacisk na moje.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak rejestrować zapytania w PostgreSQL

  2. Jak wstrzymać wykonywanie instrukcji w PostgreSQL

  3. Jak uruchomić PostgreSQL w systemie Windows?

  4. Jak ponownie wykorzystać wynik dla klauzul SELECT, WHERE i ORDER BY?

  5. Jak wyszukać konkretną wartość we wszystkich tabelach (PostgreSQL)?