Ответ 1
Поскольку PRIMARY KEY
делает столбец NOT NULL
автоматически. Я цитирую руководство здесь:
Ограничение первичного ключа указывает, что столбец или столбцы таблица может содержать только уникальные (не дублирующиеся), ненулевые значения. Технически
PRIMARY KEY
представляет собой просто комбинациюUNIQUE
иNOT NULL
.
Смелый акцент мой.
Я проверил тест, чтобы подтвердить это (против моего прежнего убеждения!) NOT NULL
полностью избыточно в сочетании с ограничением PRIMARY KEY
(в текущей реализации, вплоть до версии 9.5). Ограничение NOT NULL остается после того, как вы сбросите ограничение PK, независимо от явного предложения NOT NULL
во время создания.
db=# CREATE TEMP TABLE foo (foo_id int PRIMARY KEY);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
db=# ALTER TABLE foo DROP CONSTRAINT foo_pkey;
ALTER TABLE
db=# \d foo
table »pg_temp_4.foo«
column | type | attribute
--------+---------+-----------
foo_id | integer | not null
Идентичное поведение, если NULL
включено в оператор CREATE
.
Однако для сохранения NOT NULL
избыточности в репозиториях кода, по-видимому, должно быть NOT NULL
. Если позже вы решите переместить ограничение pk, вы можете забыть отметить столбец NOT NULL
- или он должен был даже быть NOT NULL
.
В Wiki Postgres TODO есть элемент , чтобы отделить NOT NULL
от ограничения PK. Таким образом, это может измениться в будущих версиях:
Переместить NOT NULL информацию ограничения на pg_constraint
В настоящее время ограничения NOT NULL хранятся в pg_attribute без указания их происхождения, например. первичные ключи. Один манифест проблема в том, что сброс ограничения PRIMARY KEY не устраняет NOT NULL. Другая проблема заключается в том, что мы должны вероятно, вынуждает NOT NULL распространяться из родительских таблиц в дети, как и ограничения CHECK. (Но затем падает ПЕРВИЧНЫЙ КЛЮЧ влияет на детей?)
Ответьте на добавленный вопрос:
Разве не лучше, если бы этот противоречивый CREATE TABLE просто не удалось?
Как объяснялось выше, этот
foo_id INTEGER NULL PRIMARY KEY
эквивалентно:
foo_id INTEGER PRIMARY KEY
Так как NULL
рассматривается как шумовое слово.
И мы не хотим, чтобы последний потерпел неудачу. Так что это не вариант.