Als je nodig gebruik een UNIQUE
. om NULL-waarden toe te staan beperking in plaats van een PRIMARY KEY
(en voeg een surrogaat PK-kolom toe, ik stel voor een serial
). Hierdoor kunnen kolommen NULL zijn:
CREATE TABLE distributor (
distributor_id serial PRIMARY KEY
, m_id integer
, x_id integer
, UNIQUE(m_id, x_id)
);
Opmerking , echter (volgens documentatie):
Met het oog op een unieke beperking worden null-waarden niet als gelijk beschouwd.
In jouw geval zou je zoiets kunnen invoeren als (1, NULL)
voor (m_id, x_id)
een willekeurig aantal keren zonder de beperking te schenden. Postgres beschouwt twee NULL-waarden nooit als gelijk - volgens definitie in de SQL-standaard.
Als u NULL
moet behandelen waarden gelijk aan om dergelijke "duplicaten" niet toe te staan, Ik zie twee opties :
1. Twee gedeeltelijke indexen
Bovendien naar de UNIQUE
beperking hierboven:
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;
Maar dit loopt snel uit de hand met meer dan twee kolommen die NULL kunnen zijn. Zie:
- Creëer een unieke beperking met null-kolommen
2. Een UNIQUE
. met meerdere kolommen index op uitdrukkingen
In plaats van de UNIEKE beperking. We hebben een gratis standaardwaarde nodig die nooit aanwezig is in betrokken kolommen, zoals -1
. Voeg CHECK
toe beperkingen om het niet toe te staan:
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))
Hoe bepaalde RDBMS dingen afhandelen is niet altijd een bruikbare indicator voor correct gedrag. De handleiding van Postgres verwijst hiernaar:
Dat betekent dat het zelfs in de aanwezigheid van een unieke beperking mogelijk is om dubbele rijen op te slaan die een null-waarde bevatten in ten minste één van de beperkte kolommen. Dit gedrag voldoet aan de SQL-standaard, maar we hebben gehoord dat andere SQL-databases deze regel mogelijk niet volgen .Wees dus voorzichtig bij het ontwikkelen van applicaties die bedoeld zijn om draagbaar te zijn.
Vetgedrukte nadruk van mij.