Om du behöver för att tillåta NULL-värden, använd en UNIQUE
begränsning istället för en PRIMARY KEY
(och lägg till en surrogat-PK-kolumn, jag föreslår en serial
). Detta tillåter kolumner att vara NULL:
CREATE TABLE distributor (
distributor_id serial PRIMARY KEY
, m_id integer
, x_id integer
, UNIQUE(m_id, x_id)
);
Obs , dock (per dokumentation):
I syfte att skapa en unik begränsning anses null-värden inte vara lika.
I ditt fall kan du ange något som (1, NULL)
för (m_id, x_id)
valfritt antal gånger utan att bryta mot begränsningen. Postgres anser aldrig två NULL-värden lika - enligt definition i SQL-standarden.
Om du behöver behandla NULL
värden är lika för att inte tillåta sådana "dubbletter", Jag ser två alternativ :
1. Två partiella index
Dessutom till UNIQUE
begränsning ovan:
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;
Men detta går snabbt ur händerna med mer än två kolumner som kan vara NULL. Se:
- Skapa en unik begränsning med nollkolumner
2. En flerkolumn UNIQUE
index på uttryck
Istället för den UNIKA begränsningen. Vi behöver ett gratis standardvärde som aldrig finns i involverade kolumner, som -1
. Lägg till CHECK
begränsningar för att inte tillåta det:
CREATE TABLE distributor (
distributor serial PRIMARY KEY
, m_id integer
, x_id integer
, CHECK (m_id <> -1)
, CHECK (x_id <> -1)
);
CREATE UNIQUE INDEX distributor_uni_idx ON distributor (COALESCE(m_id, -1)
, COALESCE(x_id, -1))
Hur vissa RDBMS hanterar saker är inte alltid en användbar indikator för korrekt beteende. Postgres-manualen tipsar om detta:
Det betyder att även i närvaro av en unik begränsning är det möjligt att lagra dubbletter av rader som innehåller ett nollvärde i minst en av de begränsade kolumnerna. Detta beteende överensstämmer med SQL-standarden, men vi har hört att andra SQL-databaser kanske inte följer denna regel .Så var försiktig när du utvecklar applikationer som är avsedda att vara portabla.
Djärv betoning min.