Nếu bạn cần để cho phép các giá trị NULL, hãy sử dụng UNIQUE
ràng buộc thay vì PRIMARY KEY
(và thêm cột PK thay thế, tôi đề xuất serial
). Điều này cho phép các cột là NULL:
CREATE TABLE distributor (
distributor_id serial PRIMARY KEY
, m_id integer
, x_id integer
, UNIQUE(m_id, x_id)
);
Lưu ý , tuy nhiên (theo tài liệu):
Với mục đích của một ràng buộc duy nhất, các giá trị rỗng không được coi là bằng nhau.
Trong trường hợp của bạn, bạn có thể nhập một cái gì đó như (1, NULL)
cho (m_id, x_id)
bất kỳ số lần nào mà không vi phạm các ràng buộc. Postgres không bao giờ coi hai giá trị NULL là bằng nhau - theo định nghĩa trong tiêu chuẩn SQL.
Nếu bạn cần xử lý NULL
các giá trị bằng để không cho phép các "bản sao" như vậy, Tôi thấy hai tùy chọn :
1. Hai chỉ mục một phần
Ngoài ra thành UNIQUE
ràng buộc ở trên:
CREATE UNIQUE INDEX dist_m_uni_idx ON distributor (m_id) WHERE x_id IS NULL;
CREATE UNIQUE INDEX dist_x_uni_idx ON distributor (x_id) WHERE m_id IS NULL;
Nhưng điều này nhanh chóng vượt qua khỏi tầm tay với hơn hai cột có thể là NULL. Xem:
- Tạo ràng buộc duy nhất với các cột rỗng
2. Một UNIQUE
nhiều cột lập chỉ mục trên các biểu thức
Thay vì ràng buộc DUY NHẤT. Chúng tôi cần một giá trị mặc định miễn phí không bao giờ xuất hiện trong các cột liên quan, như -1
. Thêm CHECK
ràng buộc để không cho phép nó:
CREATE TABLE distributor (
distributor serial PRIMARY KEY
, m_id integer
, x_id integer
, CHECK (m_id <> -1)
, CHECK (x_id <> -1)
);
CREATE UNIQUE INDEX distributor_uni_idx ON distributor (COALESCE(m_id, -1)
, COALESCE(x_id, -1))
Cách một số RDBMS xử lý mọi thứ không phải lúc nào cũng là một chỉ báo hữu ích cho hành vi đúng đắn. Hướng dẫn sử dụng Postgres gợi ý điều này:
Điều đó có nghĩa là ngay cả khi có một ràng buộc duy nhất, vẫn có thể lưu trữ các hàng trùng lặp chứa giá trị null trong ít nhất một trong các cột bị ràng buộc. Hành vi này tuân theo tiêu chuẩn SQL, nhưng chúng tôi đã nghe nói rằng các cơ sở dữ liệu SQL khác có thể không tuân theo quy tắc này Vì vậy, hãy cẩn thận khi phát triển các ứng dụng nhằm mục đích di động.
Nhấn mạnh đậm của tôi.