PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Composite PRIMARY KEY thực thi các ràng buộc KHÔNG ĐẦY ĐỦ trên các cột liên quan

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ó:

Nhà phân phối
CREATE TABLE distributor (
   distributor serial PRIMARY KEY
 , m_id integer
 , x_id integer
 , CHECK (m_id &lt> -1)
 , CHECK (x_id &lt> -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.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. tệp postgres db - tệp nào đại diện cho bảng / chỉ mục cụ thể?

  2. lỗi câu lệnh sql:cột .. không tồn tại

  3. PostgreSQL unnest () với số phần tử

  4. INITCAP () - Chuyển đổi sang Caps ban đầu trong PostgreSQL

  5. Heroku pg:pull không điền giản đồ