Sự khác nhau giữa MATCH FULL, MATCH SIMPLE và MATCH PARTIAL?


29

Tôi đã nhận thấy một MATCH SIMPLEMATCH FULL, nhưng tôi không hiểu những gì họ làm. Tôi thấy mặc định là MATCH SIMPLE; nhưng, làm thế nào để các MATCHmệnh đề khác cho FOREIGN KEYhàm ràng buộc?

Câu trả lời:


38

Kiểm tra CREATE TABLEtrang hướng dẫn :

Có ba loại kết hợp: MATCH FULL, MATCH PARTIAL, và MATCH SIMPLE (đó là mặc định). MATCH FULLsẽ không cho phép một cột của khóa ngoại nhiều màu là null trừ khi tất cả các cột khóa ngoại là null; nếu tất cả đều là null, hàng không bắt buộc phải có kết quả khớp trong bảng được tham chiếu. MATCH SIMPLEcho phép bất kỳ cột khóa ngoại nào là null; nếu bất kỳ trong số chúng là null, hàng không bắt buộc phải có một kết quả khớp trong bảng được tham chiếu. MATCH PARTIALvẫn chưa được thực hiện. (Tất nhiên, các NOT NULLràng buộc có thể được áp dụng cho (các) cột tham chiếu để ngăn các trường hợp này phát sinh.)

Ngoài ra, trong chương về Khóa ngoại :

Thông thường, một hàng tham chiếu không cần phải thỏa mãn ràng buộc khóa ngoài nếu bất kỳ cột tham chiếu nào của nó là null. Nếu MATCH FULL được thêm vào khai báo khóa ngoại, một hàng tham chiếu sẽ thoát thỏa mãn ràng buộc chỉ khi tất cả các cột tham chiếu của nó là null (do đó, một hỗn hợp các giá trị null và không null được đảm bảo không MATCH FULL bị ràng buộc). Nếu bạn không muốn các hàng tham chiếu có thể tránh thỏa mãn ràng buộc khóa ngoại, hãy khai báo (các) cột tham chiếu là NOT NULL.

Và hãy chắc chắn tham khảo hướng dẫn hiện tại hoặc phiên bản phù hợp với cài đặt của bạn. Đừng để các liên kết Google lỗi thời thành các phiên bản lỗi thời.


7

FULLđấu SIMPLEvớiPARTIAL

Mặc dù câu trả lời được chọn là chính xác, nhưng nếu điều này là mới đối với bạn, bạn có thể muốn xem nó bằng mã - tôi nghĩ rằng việc tìm hiểu theo cách đó sẽ dễ dàng hơn.

-- one row with (1,1)
CREATE TABLE foo ( a int, b int,
  PRIMARY KEY (a,b)
);
INSERT INTO foo (a,b) VALUES (1,1);

--
-- two child tables to reference it
-- 
CREATE TABLE t_full ( a int, b int,
  FOREIGN KEY (a,b) REFERENCES foo MATCH FULL
);
CREATE TABLE t_simple ( a int, b int,
  FOREIGN KEY (a,b) REFERENCES foo MATCH SIMPLE
);

Theo logic, với FULLSIMPLE, chúng ta có thể chèn một trận đấu đầy đủ.

-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);

Vấn đề xảy ra khi một trong các cột là NULL.

-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);

-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);

Việc chèn vào t_fulltạo ra lỗi sau,

ERROR:  insert or update on table "t_full" violates foreign key constraint "t_full_a_fkey"
DETAIL:  MATCH FULL does not allow mixing of null and nonnull key values.
INSERT 0 1

Ok, vậy thì sao (42,NULL)- đây là phần mà tôi luôn thấy khó hiểu MATCH SIMPLE,

-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);

Hành vi trên sẽ KHÔNG hoạt động với người chưa thực hiện MATCH PARTIAL, có khả năng thực hiện những gì bạn muốn cho một chỉ mục tổng hợp trong đó cột ngoài cùng bên phải được NULLđưa ra. Tuy nhiên, một số người coi đó là một phương pháp mở hộp Pandora để thiết kế xấu.

Định nghĩa đơn giản & ghi nhớ

  • MATCH FULLmọi thứ phải khớp hoàn toàn hoặc tất cả các cột phảiNULL
  • MATCH SIMPLEnếu một điều là NULLcác ràng buộc chỉ đơn giản là bỏ qua.
  • MATCH PARTIALnếu có một điều NULLthực tế là không phải mọi thứ đang NULLđược một phần vớt bằng cách làm một cái gì đó hợp lý với mục đích hạn chế.

Ghi chú SQL

Đối với hậu thế, đây là các định nghĩa từ SQL Spec trên <match type>

  • MATCH SIMPLEnếu ít nhất một cột tham chiếu là null, thì hàng của bảng tham chiếu sẽ vượt qua kiểm tra ràng buộc. Nếu tất cả các cột tham chiếu không phải là null, thì hàng sẽ vượt qua kiểm tra ràng buộc khi và chỉ khi có một hàng của bảng được tham chiếu khớp với tất cả các cột tham chiếu.
  • MATCH PARTIAL: nếu tất cả các cột tham chiếu là null, thì hàng của bảng tham chiếu sẽ vượt qua kiểm tra ràng buộc. Nếu ít nhất một cột tham chiếu không phải là null, thì hàng sẽ vượt qua kiểm tra ràng buộc nếu và chỉ khi có một hàng của bảng được tham chiếu khớp với tất cả các cột tham chiếu không null.
  • MATCH FULL: nếu tất cả các cột tham chiếu là null, thì hàng của bảng tham chiếu sẽ vượt qua kiểm tra ràng buộc. Nếu tất cả các cột tham chiếu không phải là null, thì hàng sẽ vượt qua kiểm tra ràng buộc khi và chỉ khi có một hàng của bảng được tham chiếu khớp với tất cả các cột tham chiếu. Nếu một số cột tham chiếu là null và một cột tham chiếu khác là không null, thì hàng của bảng tham chiếu vi phạm kiểm tra ràng buộc.

Mặc dù đây không phải là PostgreQuery cụ thể, nhưng các ví dụ này được thể hiện với PostgreSQL

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.