sql >> Databáze >  >> RDS >> PostgreSQL

Proč mohu vytvořit tabulku s PRIMARY KEY ve sloupci s možnou hodnotou Null?

Protože PRIMARY KEY dělá zahrnuté sloupce NOT NULL automaticky . Zde cituji manuál:

Omezení primárního klíče určuje, že sloupec nebo sloupce tabulky mohou obsahovat pouze jedinečné (neduplicitní), nenulové hodnoty. Technicky PRIMARY KEY je pouze kombinací UNIQUE a NOT NULL .

Tučné zdůraznění moje.

Provedl jsem test, abych potvrdil, že NOT NULL je v kombinaci s PRIMARY KEY zcela redundantní omezení (v aktuální implementaci, znovu testováno ve verzi 13). NOT NULL omezení zůstává i po zrušení omezení PK, bez ohledu na explicitní NOT NULL doložka v době vytvoření.

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<>zde hrajte

Identické chování, pokud NULL je součástí CREATE TABLE prohlášení.

Stále nebude na škodu ponechat NOT NULL redundantně v úložištích kódu, pokud má být sloupec NOT NULL . Pokud se později rozhodnete změnit omezení PK, možná zapomenete označit sloupec NOT NULL - nebo zda to dokonce mělo být NOT NULL .

Ve wiki Postgres TODO je položka k oddělení NOT NULL z omezení PK. To se tedy může v budoucích verzích změnit:

Přesuňte informace o omezení NOT NULL do pg_constraint

V současné době jsou omezení NOT NULL uložena v pg_attribute bez jakéhokoli označení jejich původu, např. primární klíče. Jedním z zjevných problémů je, že zrušením omezení PRIMARY KEY se neodstraní označení omezení NOT NULL. Dalším problémem je, že bychom pravděpodobně měli vynutit šíření NOT NULL z rodičovských tabulek dětem, stejně jako omezení CHECK. (Ovlivňuje však vypuštění PRIMARY KEY děti?)

Odpověď na přidanou otázku

Nebylo by lepší, kdyby tato protichůdná CREATE TABLE právě tam selhala?

Jak je vysvětleno výše, toto

foo_id INTEGER NULL PRIMARY KEY

je (aktuálně) 100 % ekvivalentní:

foo_id INTEGER PRIMARY KEY

Od NULL je v tomto kontextu považováno za šumové slovo.
A my bychom nechtěli, aby to druhé selhalo. Takže toto není možnost.



  1. Jak zobrazit datum ve formátu data v USA na serveru SQL (T-SQL)

  2. Používejte relační databáze MySQL na Ubuntu 9.10 (Karmic)

  3. Vypočítejte časový rozdíl mezi dvěma řádky

  4. BEGIN - END blokové atomické transakce v PL/SQL