Tôi gặp sự cố tương tự với ALTER TABLE ADD FOREIGN KEY
.
Sau một giờ, tôi thấy rằng các điều kiện này phải được thỏa mãn để không gặp lỗi 150:
-
Bảng chính phải tồn tại trước khi bạn xác định khóa ngoại để tham chiếu nó. Bạn phải xác định các bảng theo đúng thứ tự:Bảng mẹ trước rồi đến bảng Con. Nếu cả hai bảng tham chiếu lẫn nhau, bạn phải tạo một bảng không có ràng buộc FK, sau đó tạo bảng thứ hai, sau đó thêm ràng buộc FK vào bảng đầu tiên bằng
ALTER TABLE
. -
Cả hai bảng đều phải hỗ trợ các ràng buộc khóa ngoại, tức là
ENGINE=InnoDB
. Các công cụ lưu trữ khác âm thầm bỏ qua các định nghĩa khóa ngoại, vì vậy chúng không trả về lỗi hoặc cảnh báo nào, nhưng ràng buộc FK không được lưu. -
Các cột được tham chiếu trong bảng Gốc phải là cột ngoài cùng bên trái của một khóa. Tốt nhất nếu khóa trong Parent là
PRIMARY KEY
hoặcUNIQUE KEY
. -
Định nghĩa FK phải tham chiếu đến (các) cột PK theo thứ tự giống như định nghĩa PK. Ví dụ:nếu FK
REFERENCES Parent(a,b,c)
thì PK của Cha mẹ không được xác định trên các cột theo thứ tự(a,c,b)
. -
(Các) cột PK trong bảng Gốc phải cùng kiểu dữ liệu với (các) cột FK trong bảng Con. Ví dụ:nếu cột PK trong bảng Gốc là
UNSIGNED
, hãy đảm bảo xác địnhUNSIGNED
cho cột tương ứng trong trường Bảng con.Ngoại lệ:độ dài của các chuỗi có thể khác nhau. Ví dụ:
VARCHAR(10)
có thể tham chiếuVARCHAR(20)
hoặc ngược lại. -
Mọi (các) cột FK kiểu chuỗi phải có cùng bộ ký tự và đối chiếu với (các) cột PK tương ứng.
-
Nếu đã có dữ liệu trong bảng Con, thì mọi giá trị trong (các) cột FK phải khớp với một giá trị trong (các) cột PK trong bảng Cha. Kiểm tra điều này bằng một truy vấn như:
SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK WHERE Parent.PK IS NULL;
Điều này phải trả về không (0) giá trị không khớp. Rõ ràng, truy vấn này là một ví dụ chung chung; bạn phải thay thế tên bảng và tên cột của mình.
-
Bảng Gốc và bảng Con đều không được là
TEMPORARY
bảng. -
Cả bảng Gốc và bảng Con đều không thể là
PARTITIONED
bảng. -
Nếu bạn khai báo FK với
ON DELETE SET NULL
tùy chọn, thì (các) cột FK phải có giá trị rỗng. -
Nếu bạn khai báo tên ràng buộc cho khóa ngoại, tên ràng buộc phải là duy nhất trong toàn bộ lược đồ, không chỉ trong bảng mà ràng buộc được định nghĩa. Hai bảng có thể không có ràng buộc riêng với cùng một tên.
-
Nếu có bất kỳ FK nào khác trong các bảng khác trỏ vào cùng một trường mà bạn đang cố gắng tạo FK mới và chúng không đúng định dạng (tức là đối chiếu khác nhau), trước tiên chúng cần được làm cho nhất quán. Đây có thể là kết quả của những thay đổi trước đây trong đó
SET FOREIGN_KEY_CHECKS = 0;
đã được sử dụng với một mối quan hệ không nhất quán được xác định do nhầm lẫn. Xem câu trả lời của @ andrewdotn bên dưới để biết hướng dẫn về cách xác định các vấn đề này của FK.
Hy vọng điều này sẽ hữu ích.