(Các) cột khóa ngoại phải tham chiếu (các) cột bao gồm tiền tố ngoài cùng bên trái của khóa chính hoặc khóa duy nhất trong bảng mẹ.
Nói cách khác, các ví dụ sau hoạt động trong InnoDB:
CREATE TABLE Foo ( a INT, b INT, c INT, PRIMARY KEY (a,b,c) );
CREATE TABLE Bar ( x INT, y INT );
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(b,c); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,c); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,b); -- RIGHT
ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(b); -- WRONG
ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(a); -- RIGHT
Bạn gặp lỗi vì bạn đang cố thực hiện tương đương với (x) tham chiếu Foo (b).
Cột codmenuitem của bạn là cột thứ hai trong số ba cột trong khóa chính của khóa chính.
Nó sẽ hoạt động nếu smenuitememp.codemenuitem
là tham chiếu smenuitem.codmodulo
, vì cột đó là cột ngoài cùng bên trái trong khóa chính của bảng mẹ.
Đặt lại câu hỏi tiếp theo của bạn:
Hãy ghi nhớ cách hoạt động của khóa ngoại. Mỗi khi bạn chèn hoặc cập nhật một hàng trong bảng con, nó cần phải tìm kiếm một hàng trong bảng mẹ để xác minh rằng giá trị tồn tại trong cột được tham chiếu. Nếu cột không được lập chỉ mục, nó sẽ phải quét bảng để đạt được tra cứu này và điều đó sẽ rất tốn kém, giả sử bảng mẹ của bạn tăng lên.
Nếu bạn cố gắng tra cứu một hàng dựa trên cột giữa của chỉ mục nhiều cột, chỉ mục này không giúp được gì cho bạn. Tương tự, nó giống như tìm kiếm trong danh bạ điện thoại của tất cả những người có tên đệm nhất định.
ANSI SQL tiêu chuẩn yêu cầu cột được tham chiếu phải là một phần của TỪ KHÓA CHÍNH hoặc TỪ KHÓA DUY NHẤT và nó yêu cầu các cột khóa ngoại phải khớp với tất cả các cột của ràng buộc chính hoặc duy nhất trong cột gốc.
Nhưng InnoDB dễ dãi hơn. Nó vẫn yêu cầu cột được tham chiếu trong bảng mẹ phải được lập chỉ mục để việc tra cứu có thể hiệu quả, và rằng các cột được tham chiếu ở ngoài cùng bên trái trong chỉ mục. Nhưng một chỉ mục không phải là duy nhất thì không sao; nó được phép cho một khóa ngoại tham chiếu đến nó.
Điều này có thể dẫn đến các trường hợp kỳ lạ như một hàng con tham chiếu đến nhiều hơn một hàng trong dòng chính, nhưng bạn có thể xử lý các trường hợp bất thường như vậy.
Tôi thấy cần phải nhấn mạnh điểm cuối cùng. Bạn sẽ nhận dữ liệu bất thường nếu bạn xác định khóa ngoại cho các cột được lập chỉ mục không phải là duy nhất trong cột chính. Điều này có thể sẽ khiến các truy vấn của bạn báo cáo các hàng nhiều lần khi bạn kết hợp. Bạn không nên sử dụng hành vi này của InnoDB; bạn chỉ nên xác định khóa ngoại cho các cột mẹ là duy nhất.