Tôi đã nhận thấy một MATCH SIMPLE
và MATCH 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 MATCH
mệnh đề khác cho FOREIGN KEY
hàm ràng buộc?
Tôi đã nhận thấy một MATCH SIMPLE
và MATCH 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 MATCH
mệnh đề khác cho FOREIGN KEY
hàm ràng buộc?
Câu trả lời:
Kiểm tra CREATE TABLE
trang hướng dẫn :
Có ba loại kết hợp:
MATCH FULL
,MATCH PARTIAL
, vàMATCH SIMPLE
(đó là mặc định).MATCH FULL
sẽ 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 SIMPLE
cho 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 PARTIAL
vẫn chưa được thực hiện. (Tất nhiên, cácNOT NULL
rà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ôngMATCH 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.
FULL
đấu SIMPLE
vớ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 FULL
và SIMPLE
, 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_full
tạ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.
MATCH FULL
mọi thứ phải khớp hoàn toàn hoặc tất cả các cột phảiNULL
MATCH SIMPLE
nếu một điều là NULL
các ràng buộc chỉ đơn giản là bỏ qua.MATCH PARTIAL
nếu có một điều NULL
thự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ế.Đối với hậu thế, đây là các định nghĩa từ SQL Spec trên <match type>
MATCH SIMPLE
nế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