sql >> Databasteknik >  >> RDS >> PostgreSQL

Varför kan jag skapa en tabell med PRIMARY KEY på en nullbar kolumn?

Eftersom PRIMARY KEY fabrikat de inkluderade kolumnerna NOT NULL automatiskt . Jag citerar manualen här:

Den primära nyckelbegränsningen anger att en kolumn eller kolumner i atable endast kan innehålla unika (icke-duplicerade), icke-nullvärden. Tekniskt sett PRIMARY KEY är bara en kombination av UNIQUE och NOT NULL .

Djärv betoning min.

Jag körde ett test för att bekräfta att NOT NULL är helt redundant i kombination med en PRIMARY KEY begränsning (i den nuvarande implementeringen, omtestad i version 13). NOT NULL restriktioner även efter att PK-begränsningen har släppts, oavsett en explicit NOT NULL klausul vid skapandet.

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<>spela här

Identiskt beteende om NULL ingår i CREATE TABLE uttalande.

Det kommer fortfarande inte att skada att behålla NOT NULL redundant i kodlager om kolumnen ska vara NOT NULL . Om du senare bestämmer dig för att ändra PK-begränsningen kan du glömma att markera kolumnen NOT NULL - eller om det ens var tänkt att vara NOT NULL .

Det finns ett objekt i Postgres TODO-wiki för att koppla bort NOT NULL från PK-begränsningen. Så detta kan ändras i framtida versioner:

Flytta NOT NULL-begränsningsinformation till pg_constraint

För närvarande lagras NOT NULL-begränsningar i pg_attribute utan någon beteckning på deras ursprung, t.ex. primära nycklar. Ett tydligt problem är att om du släpper en PRIMARY KEY-begränsning inte tar bort NOT NULL-begränsningsbeteckningen. En annan fråga är att vi förmodligen borde tvinga NOT NULL att spridas från överordnade tabeller till barn, precis som CHECK-begränsningar är. (Men påverkar det barn då att tappa PRIMÄRNYCKEL?)

Svar på tillagd fråga

Skulle det inte vara bättre om detta självmotsägande CREATE TABLE bara misslyckades just där?

Som förklarats ovan, detta

foo_id INTEGER NULL PRIMARY KEY

motsvarar (för närvarande) 100 %:

foo_id INTEGER PRIMARY KEY

Sedan NULL behandlas som brusord i detta sammanhang.
Och vi vill inte att det senare ska misslyckas. Så detta är inte ett alternativ.



  1. Mytop – Ett användbart verktyg för att övervaka MySQL/MariaDB-prestanda i Linux

  2. Massinlägg eller uppdatering för tabeller med bifogade fält

  3. Hur SQLite Ifnull() fungerar

  4. Automatisera Barman med Puppet:it2ndq/barman (del ett)