sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvorfor kan jeg oprette en tabel med PRIMARY KEY på en nullbar kolonne?

Fordi PRIMARY KEY gør de inkluderede kolonne(r) NOT NULL automatisk . Jeg citerer manualen her:

Den primære nøglebegrænsning specificerer, at en kolonne eller kolonner af atable kun kan indeholde unikke (ikke-duplikerede), ikke-null-værdier. Teknisk set PRIMARY KEY er blot en kombination af UNIQUE og NOT NULL .

Fed fremhævelse mine.

Jeg kørte en test for at bekræfte, at NOT NULL er fuldstændig redundant i kombination med en PRIMARY KEY begrænsning (i den nuværende implementering, gentestet i version 13). NOT NULL begrænsning forbliver selv efter at have droppet PK-begrænsningen, uanset en eksplicit NOT NULL klausul på oprettelsestidspunktet.

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<>spil her

Identisk adfærd hvis NULL er inkluderet i CREATE TABLE erklæring.

Det vil stadig ikke skade at beholde NOT NULL redundant i kodelagre, hvis kolonnen formodes at være NOT NULL . Hvis du senere beslutter dig for at ændre PK-begrænsningen, glemmer du muligvis at markere kolonnen NOT NULL - eller om det overhovedet skulle være NOT NULL .

Der er et element i Postgres TODO wiki, der skal afkoble NOT NULL fra PK-begrænsningen. Så dette kan ændre sig i fremtidige versioner:

Flyt NOT NULL-begrænsningsoplysninger til pg_constraint

I øjeblikket er NOT NULL-begrænsninger gemt i pg_attribute uden nogen betegnelse for deres oprindelse, f.eks. primære nøgler. Et tydeligt problem er, at droppe en PRIMARY KEY-begrænsning ikke fjerner NOT NULL-betingelsen. Et andet problem er, at vi sandsynligvis skal tvinge NOT NULL til at blive udbredt fra overordnede tabeller til børn, ligesom CHECK-begrænsninger er. (Men så påvirker det børn at droppe PRIMÆR NØGLE?)

Svar på tilføjet spørgsmål

Ville det ikke være bedre, hvis dette selvmodsigende CREATE TABLE bare mislykkedes lige dér?

Som forklaret ovenfor er dette

foo_id INTEGER NULL PRIMARY KEY

svarer (i øjeblikket) 100 % til:

foo_id INTEGER PRIMARY KEY

Siden NULL behandles som støjord i denne sammenhæng.
Og vi ønsker ikke, at sidstnævnte fejler. Så dette er ikke en mulighed.



  1. Sådan sorteres resultatet fra string_agg()

  2. Søg efter en bestemt streng i Oracle clob-kolonnen

  3. Hvilke metoder kan bruges til at administrere forskellige versioner af allerede eksisterende databaser?

  4. SQL Server 2008 tusinde separator for en kolonne