sql >> Database >  >> RDS >> PostgreSQL

Waarom kan ik een tabel maken met PRIMARY KEY op een nullable kolom?

Omdat de PRIMARY KEY maakt de opgenomen kolom(men) NOT NULL automatisch . Ik citeer hier de handleiding:

De primaire sleutelbeperking geeft aan dat een kolom of kolommen van atable alleen unieke (niet-dubbele), niet-null waarden kunnen bevatten. Technisch gezien, PRIMARY KEY is slechts een combinatie van UNIQUE en NOT NULL .

Vetgedrukte nadruk van mij.

Ik heb een test uitgevoerd om te bevestigen dat NOT NULL is volledig redundant in combinatie met een PRIMARY KEY beperking (in de huidige implementatie, opnieuw getest in versie 13). De NOT NULL beperking blijft zelfs na het laten vallen van de PK-beperking, ongeacht een expliciete NOT NULL clausule op het moment van aanmaak.

CREATE TABLE foo (foo_id int PRIMARY KEY);
ALTER TABLE foo DROP CONSTRAINT foo_pkey;
db=# \d foo
   table »public.foo«
 column |  type   | attribute
--------+---------+-----------
 foo_id | integer | not null    -- stays

db<>viool hier

Identiek gedrag als NULL is opgenomen in de CREATE TABLE verklaring.

Het kan nog steeds geen kwaad om NOT NULL . te behouden redundant in coderepositories als de kolom verondersteld wordt NOT NULL te zijn . Als u later besluit de PK-beperking te wijzigen, vergeet u misschien de kolom NOT NULL aan te vinken. - of dat het zelfs de bedoeling was NOT NULL te zijn .

Er is een item in de Postgres TODO-wiki om NOT NULL te ontkoppelen van de PK-beperking. Dit kan dus veranderen in toekomstige versies:

Verplaats NOT NULL-beperkingsinformatie naar pg_constraint

Momenteel worden NOT NULL-beperkingen opgeslagen in pg_attribute zonder enige aanduiding van hun oorsprong, b.v. primaire sleutels. Een manifestprobleem is dat het weglaten van een PRIMARY KEY-beperking de aanduiding NOT NULL-beperking niet verwijdert. Een ander probleem is dat we waarschijnlijk NOT NULL moeten forceren om van bovenliggende tabellen naar kinderen te worden gepropageerd, net zoals CHECK-beperkingen zijn. (Maar heeft het laten vallen van de PRIMARY KEY dan invloed op kinderen?)

Antwoord op toegevoegde vraag

Zou het niet beter zijn als deze tegenstrijdige CREATE TABLE daar gewoon zou mislukken?

Zoals hierboven uitgelegd, is deze

foo_id INTEGER NULL PRIMARY KEY

is (momenteel) 100 % gelijk aan:

foo_id INTEGER PRIMARY KEY

Sinds NULL wordt in deze context behandeld als een ruiswoord.
En we zouden niet willen dat dit laatste faalde. Dit is dus geen optie.



  1. RMAN-opdrachten mislukken met ORA-00904:"BS". "GUID":ongeldige identifier

  2. Waarom is het gebruik van een op mysql voorbereide instructie veiliger dan het gebruik van de algemene escape-functies?

  3. Een kolom wijzigen:null in niet null

  4. LOCALTIMESTAMP() Functie in Oracle