Không ổn. Tham chiếu vòng giữa các bảng là lộn xộn. Xem bài viết (đã có từ thập kỷ này): SQL By Design:Tham chiếu Thông tư
Một số DBMS có thể xử lý những điều này và với sự cẩn thận đặc biệt, nhưng MySQL sẽ có vấn đề.
Tùy chọn 1
Như thiết kế của bạn, để làm cho một trong hai FK có thể bị vô hiệu hóa. Điều này cho phép bạn giải quyết vấn đề con gà và quả trứng (trước tiên tôi nên Chèn vào bảng nào?).
Có một vấn đề với mã của bạn. Nó sẽ cho phép một sản phẩm có hình ảnh mặc định trong đó hình ảnh đó sẽ tham chiếu đến sản phẩm khác!
Để không cho phép một lỗi như vậy, ràng buộc FK của bạn phải là:
CONSTRAINT FK_products_1
FOREIGN KEY (id, default_picture_id)
REFERENCES products_pictures (product_id, id)
ON DELETE RESTRICT --- the SET NULL options would
ON UPDATE RESTRICT --- lead to other issues
Điều này sẽ yêu cầu UNIQUE
ràng buộc / chỉ mục trong bảng products_pictures
trên (product_id, id)
để FK trên được xác định và hoạt động bình thường.
Tùy chọn 2
Một cách tiếp cận khác là loại bỏ Default_Picture_ID
tạo thành cột product
bảng và thêm một IsDefault BIT
trong picture
bàn. Vấn đề của giải pháp này là làm thế nào để chỉ cho phép một bức ảnh trên mỗi sản phẩm có bit đó và tất cả những bức ảnh khác đều tắt nó đi. Trong SQL-Server (và tôi nghĩ trong Postgres) điều này có thể được thực hiện với một chỉ mục một phần:
CREATE UNIQUE INDEX is_DefaultPicture
ON products_pictures (Product_ID)
WHERE IsDefault = 1 ;
Nhưng MySQL không có tính năng này.
Tùy chọn 3
Cách tiếp cận này, cho phép bạn thậm chí có cả hai cột FK được xác định là NOT NULL
là sử dụng các ràng buộc có thể hoãn lại. Điều này hoạt động trong PostgreSQL và tôi nghĩ trong Oracle. Kiểm tra câu hỏi này và câu trả lời của @Erwin: Ràng buộc khóa ngoại phức tạp trong SQLAlchemy
( Tất cả các cột chính KHÔNG ĐẦY ĐỦ Phần).
Các ràng buộc trong MySQL không thể được hoãn lại.
Tùy chọn 4
Cách tiếp cận (mà tôi thấy rõ ràng nhất) là loại bỏ Default_Picture_ID
cột và thêm một bảng khác. Không có đường dẫn tròn nào trong các ràng buộc FK và tất cả các cột FK sẽ là NOT NULL
với giải pháp này:
product_default_picture
----------------------
product_id NOT NULL
default_picture_id NOT NULL
PRIMARY KEY (product_id)
FOREIGN KEY (product_id, default_picture_id)
REFERENCES products_pictures (product_id, id)
Điều này cũng sẽ yêu cầu UNIQUE
ràng buộc / chỉ mục trong bảng products_pictures
trên (product_id, id)
như trong giải pháp 1.
Tóm lại, với MySQL, bạn có hai tùy chọn:
-
tùy chọn 1 (cột FK có thể vô hiệu hóa) với phần sửa chữa ở trên để thực thi tính toàn vẹn một cách chính xác
-
tùy chọn 4 (không có cột FK có thể vô hiệu)