sql >> Database >  >> RDS >> PostgreSQL

Samengestelde PRIMARY KEY dwingt NOT NULL-beperkingen af ​​op betrokken kolommen

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 &lt> -1)
 , CHECK (x_id &lt> -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.




  1. PL/Proxy compileren met PostgresPlus Advance Server 9.1

  2. Hoe een mysql-database exporteren met behulp van de opdrachtprompt?

  3. Zoek verwijzende entiteiten in SQL Server:sys.dm_sql_referencing_entities()

  4. Rijprestaties voor PostgreSQL met HAProxy