PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Dlaczego mogę utworzyć tabelę z PRIMARY KEY na kolumnie dopuszczającej wartość null?

Ponieważ PRIMARY KEY produkuje dołączone kolumny NOT NULL automatycznie . Cytuję instrukcję tutaj:

Ograniczenie klucza podstawowego określa, że ​​kolumna lub kolumny atable mogą zawierać tylko unikalne (nie zduplikowane) wartości inne niż null.Technicznie PRIMARY KEY jest tylko kombinacją UNIQUE i NOT NULL .

Pogrubiony nacisk na moje.

Przeprowadziłem test, aby potwierdzić, że NOT NULL jest całkowicie nadmiarowy w połączeniu z PRIMARY KEY ograniczenie (w obecnej implementacji, ponownie przetestowane w wersji 13). NOT NULL ograniczenie pozostaje nawet po usunięciu ograniczenia PK, niezależnie od jawnego NOT NULL klauzula w czasie tworzenia.

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<>graj tutaj

Identyczne zachowanie, jeśli NULL znajduje się w CREATE TABLE oświadczenie.

Nadal nie zaszkodzi zachować NOT NULL nadmiarowo w repozytoriach kodu, jeśli kolumna ma być NOT NULL . Jeśli później zdecydujesz się zmienić ograniczenie PK, możesz zapomnieć o zaznaczeniu kolumny NOT NULL - czy w ogóle miał być NOT NULL .

W wiki Postgres TODO znajduje się element, który umożliwia rozdzielenie NOT NULL z ograniczenia PK. Może się to zmienić w przyszłych wersjach:

Przenieś informacje o ograniczeniu NOT NULL do pg_constraint

Obecnie ograniczenia NOT NULL są przechowywane w pg_attribute bez podania ich pochodzenia, np. klucze podstawowe. Jednym z przejawów problemu jest to, że usunięcie ograniczenia KLUCZ PODSTAWOWY nie powoduje usunięcia oznaczenia ograniczenia NOT NULL. Inną kwestią jest to, że powinniśmy prawdopodobnie wymusić propagowanie wartości NOT NULL z tabel nadrzędnych do dzieci, tak jak w przypadku ograniczeń CHECK. (Ale czy porzucenie PRIMARY KEY wpływa na dzieci?)

Odpowiedź na dodane pytanie

Czy nie byłoby lepiej, gdyby ta wewnętrznie sprzeczna CREATE TABLE po prostu zawiodła?

Jak wyjaśniono powyżej, to

foo_id INTEGER NULL PRIMARY KEY

jest (obecnie) w 100% odpowiednikiem:

foo_id INTEGER PRIMARY KEY

Od NULL jest traktowane jako słowo szumu w tym kontekście.
I nie chcielibyśmy, aby to drugie zawiodło. Więc to nie jest opcja.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Co to znaczy, że proces PostgreSQL jest bezczynny w transakcji?

  2. Początkowa tablica w funkcji agregacji tablicy wielowymiarowej

  3. Zapisz dane wyjściowe z funkcji sql do pliku csv (KOPIUJ) z dynamiczną nazwą pliku

  4. Jak dodać kolumnę, jeśli nie istnieje w PostgreSQL?

  5. Pomyłka portu postgresql 5433 czy 5432?