Bởi vì PRIMARY KEY
làm cho (các) cột được bao gồm NOT NULL
tự động . Tôi trích dẫn sách hướng dẫn ở đây:
Ràng buộc khóa chính chỉ định rằng một cột hoặc các cột có thể sử dụng chỉ có thể chứa các giá trị duy nhất (không trùng lặp), không rỗng. Về mặt kỹ thuật,
PRIMARY KEY
chỉ là sự kết hợp củaUNIQUE
vàNOT NULL
.
Nhấn mạnh đậm của tôi.
Tôi đã chạy kiểm tra để xác nhận rằng NOT NULL
hoàn toàn dư thừa khi kết hợp với PRIMARY KEY
ràng buộc (trong triển khai hiện tại, đã được kiểm tra lại trong phiên bản 13). NOT NULL
hạn chế ở lại ngay cả sau khi bỏ ràng buộc PK, không có NOT NULL
rõ ràng tại thời điểm tạo.
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 <> fiddle here
Hành vi giống hệt nhau nếu NULL
được đưa vào CREATE TABLE
tuyên bố.
Vẫn không sao nếu giữ NOT NULL
dư thừa trong kho mã nếu cột được cho là NOT NULL
. Nếu sau đó bạn quyết định thay đổi ràng buộc PK, bạn có thể quên đánh dấu cột NOT NULL
- hoặc liệu nó thậm chí được cho là NOT NULL
.
Có một mục trong wiki Postgres TODO để tách NOT NULL
khỏi ràng buộc PK. Vì vậy, điều này có thể thay đổi trong các phiên bản tương lai:
Di chuyển thông tin ràng buộc NOT NULL sang pg_constraint
Hiện tại, các ràng buộc NOT NULL được lưu trữ trong pg_attribute mà không có bất kỳ chỉ định nào về nguồn gốc của chúng, ví dụ:khóa chính. Một vấn đề trong bản kê khai là việc bỏ một ràng buộc CHÍNH CHÍNH không loại bỏ được chỉ định ràng buộc KHÔNG ĐẦY ĐỦ. Một vấn đề khác là chúng ta có thể buộc NOT NULL được truyền từ bảng cha sang bảng con, giống như ràng buộc CHECK. (Nhưng sau đó, dropPRIMARY KEY có ảnh hưởng đến trẻ em không?)
Câu trả lời cho câu hỏi đã thêm
Sẽ không tốt hơn nếu CREATE TABLE tự mâu thuẫn này không thành công ngay tại đó?
Như đã giải thích ở trên, điều này
foo_id INTEGER NULL PRIMARY KEY
là (hiện tại) 100% tương đương với:
foo_id INTEGER PRIMARY KEY
Kể từ khi NULL
được coi là từ nhiễu trong ngữ cảnh này.
Và chúng tôi sẽ không muốn lỗi sau. Vì vậy, đây không phải là một tùy chọn.