PRIMARY KEY 作る 含まれている列NOT NULL 自動的に 。ここでマニュアルを引用します:
主キー制約は、atableの1つまたは複数の列に一意の(重複しない)非null値のみを含めることができることを指定します。技術的には、
PRIMARY KEYUNIQUEの単なる組み合わせです およびNOT NULL。
大胆な強調鉱山。
テストを実行して、NOT NULLであることを確認しました PRIMARY KEYと組み合わせて完全に冗長です 制約(現在の実装では、バージョン13で再テストされています)。 NOT NULL 制約は残ります 明示的なNOT NULLに関係なく、PK制約を削除した後でも 作成時の句。
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<>ここでフィドル
NULLの場合は同じ動作 CREATE TABLEに含まれています ステートメント。
NOT NULLを維持しても問題はありません 列がNOT NULLであると想定される場合、コードリポジトリで冗長になります 。後でPK制約を変更することにした場合、列にNOT NULLのマークを付けるのを忘れる可能性があります。 -または、NOT NULLであると想定されていたかどうか 。
Postgres TODO wikiには、NOT NULLを分離するためのアイテムがあります。 PK制約から。したがって、これは将来のバージョンで変更される可能性があります:
NOTNULL制約情報をpg_constraintに移動します
現在、NOT NULL制約は、その起源を指定せずにpg_attributeに格納されています。主キー。マニフェストの問題の1つは、PRIMARY KEY制約を削除しても、NOTNULL制約の指定が削除されないことです。もう1つの問題は、CHECK制約と同様に、おそらくNOTNULLを親テーブルから子に伝搬するように強制する必要があることです。 (しかし、dropingPRIMARY KEYは子供に影響しますか?)
追加された質問への回答
この自己矛盾するCREATETABLEがすぐに失敗したとしたら、それは良いことではないでしょうか?
上で説明したように、これは
foo_id INTEGER NULL PRIMARY KEY
(現在)100%同等です:
foo_id INTEGER PRIMARY KEY
NULL以降 この文脈ではノイズワードとして扱われます。
そして、後者が失敗することは望ましくありません。したがって、これはオプションではありません。