Hvis du bruger for at tillade NULL-værdier skal du bruge en UNIQUE
begrænsning i stedet for en PRIMARY KEY
(og tilføje en surrogat-PK-kolonne, jeg foreslår en serial
). Dette tillader kolonner at være NULL:
CREATE TABLE distributor (
distributor_id serial PRIMARY KEY
, m_id integer
, x_id integer
, UNIQUE(m_id, x_id)
);
Bemærk dog (pr. dokumentation):
Med henblik på en unik begrænsning anses null-værdier ikke for at være ens.
I dit tilfælde kan du indtaste noget som (1, NULL)
for (m_id, x_id)
et vilkårligt antal gange uden at overtræde begrænsningen. Postgres betragter aldrig to NULL-værdier som lige - som per definition i SQL-standarden.
Hvis du har brug for at behandle NULL
værdier som lig for at ikke tillade sådanne "duplikater", Jeg ser to muligheder :
1. To delvise indekser
Desuden til UNIQUE
begrænsning ovenfor:
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 dette kommer hurtigt ud af hænderne med mere end to kolonner, der kan være NULL. Se:
- Opret en unik begrænsning med null-kolonner
2. En multi-kolonne UNIQUE
indeks på udtryk
I stedet for den UNIKKE begrænsning. Vi har brug for en gratis standardværdi, der aldrig er til stede i involverede kolonner, såsom -1
. Tilføj CHECK
begrænsninger for at ikke tillade 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))
Hvordan visse RDBMS håndterer ting er ikke altid en nyttig indikator for korrekt adfærd. Postgres-manualen antyder dette:
Det betyder, at selv i tilstedeværelsen af en unik begrænsning er det muligt at gemme duplikerede rækker, der indeholder en nulværdi i mindst én af de begrænsede kolonner. Denne adfærd er i overensstemmelse med SQL-standarden, men vi har hørt, at andre SQL-databaser muligvis ikke følger denne regel .Så vær forsigtig, når du udvikler applikationer, der er beregnet til at være bærbare.
Fed fremhævelse mine.