Nein, es ist nicht in Ordnung. Zirkelverweise zwischen Tabellen sind chaotisch. Siehe diesen (zehn Jahre alten) Artikel:SQL By Design:The Circular Reference
Einige DBMS können damit umgehen, und zwar mit besonderer Sorgfalt, aber MySQL wird Probleme haben.
Möglichkeit 1
Als Ihr Design, um einen der beiden FKs nullable zu machen. Damit lösen Sie das Henne-Ei-Problem (in welche Tabelle soll ich zuerst einfügen?).
Es gibt jedoch ein Problem mit Ihrem Code. Dadurch kann ein Produkt ein Standardbild haben, wobei dieses Bild auf ein anderes Produkt verweist!
Um einen solchen Fehler zu verhindern, sollte Ihre FK-Einschränkung wie folgt lauten:
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
Dies erfordert einen UNIQUE
Einschränkung/Index in Tabelle products_pictures
auf (product_id, id)
damit der obige FK definiert ist und richtig funktioniert.
Option 2
Ein anderer Ansatz besteht darin, die Default_Picture_ID
zu entfernen Spalte bilden das product
Tabelle und fügen Sie ein IsDefault BIT
hinzu Spalte im picture
Tisch. Das Problem bei dieser Lösung besteht darin, dass nur bei einem Bild pro Produkt dieses Bit aktiviert und bei allen anderen deaktiviert werden kann. In SQL-Server (und ich glaube in Postgres) kann dies mit einem Teilindex erfolgen:
CREATE UNIQUE INDEX is_DefaultPicture
ON products_pictures (Product_ID)
WHERE IsDefault = 1 ;
Aber MySQL hat keine solche Funktion.
Möglichkeit 3
Mit diesem Ansatz können Sie sogar beide FK-Spalten als NOT NULL
definieren ist es, aufschiebbare Einschränkungen zu verwenden. Dies funktioniert in PostgreSQL und ich denke in Oracle. Überprüfen Sie diese Frage und die Antwort von @Erwin:Komplexe Fremdschlüsselbeschränkung in SQLAlchemy
(die Alle Schlüsselspalten NICHT NULL Teil).
Beschränkungen in MySQL können nicht verschoben werden.
Option 4
Der Ansatz (den ich am saubersten finde) besteht darin, die Default_Picture_ID
zu entfernen Spalte und fügen Sie eine weitere Tabelle hinzu. Kein kreisförmiger Pfad in den FK-Einschränkungen und alle FK-Spalten sind NOT NULL
mit dieser Lösung:
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)
Dies erfordert auch einen UNIQUE
Einschränkung/Index in Tabelle products_pictures
auf (product_id, id)
wie in Lösung 1.
Zusammenfassend haben Sie mit MySQL zwei Möglichkeiten:
-
Option 1 (eine Nullable-FK-Spalte) mit der obigen Korrektur, um die Integrität korrekt zu erzwingen
-
Option 4 (keine Nullable-FK-Spalten)