Ne, to není v pořádku. Kruhové odkazy mezi tabulkami jsou chaotické. Podívejte se na tento (dekádu starý) článek:SQL By Design:The Circular Reference
Některé DBMS to zvládnou a se zvláštní péčí, ale MySQL bude mít problémy.
Možnost 1
Jako váš návrh, aby byl jeden ze dvou FK neplatný. To vám umožní vyřešit problém s kuřecím masem a vejci (do které tabulky mám vložit jako první?).
S vaším kódem je však problém. To umožní produktu mít výchozí obrázek, kde tento obrázek bude odkazovat na jiný produkt!
Chcete-li takovou chybu zakázat, vaše omezení FK by mělo být:
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
To bude vyžadovat UNIQUE omezení/index v tabulce products_pictures na (product_id, id) aby výše uvedené FK byly definovány a správně fungovaly.
Možnost 2
Dalším způsobem je odstranění Default_Picture_ID ze sloupce product tabulku a přidejte IsDefault BIT ve sloupci picture stůl. Problém s tímto řešením je, jak povolit pouze jednomu obrázku na produkt, aby měl tento bit zapnutý, a všem ostatním jej mít vypnutý. V SQL-Serveru (a myslím, že v Postgresu) to lze provést pomocí částečného indexu:
CREATE UNIQUE INDEX is_DefaultPicture
ON products_pictures (Product_ID)
WHERE IsDefault = 1 ;
MySQL však žádnou takovou funkci nemá.
Možnost 3
Tento přístup vám dokonce umožňuje mít oba sloupce FK definované jako NOT NULL je použití odložitelných omezení. Toto funguje v PostgreSQL a myslím, že v Oracle. Zkontrolujte tuto otázku a odpověď od @Erwin:Komplexní omezení cizího klíče v SQLAlchemy
(Všechny klíčové sloupce NOT NULL Část).
Omezení v MySQL nelze odložit.
Možnost 4
Přístup (který považuji za nejčistší) je odstranit Default_Picture_ID sloupec a přidejte další tabulku. Žádná kruhová cesta ve vazbách FK a všechny sloupce FK budou NOT NULL s tímto řešením:
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)
To bude také vyžadovat UNIQUE omezení/index v tabulce products_pictures na (product_id, id) jako v řešení 1.
Abych to shrnul, s MySQL máte dvě možnosti:
-
možnost 1 (sloupec FK s možnou hodnotou null) s výše uvedenou opravou pro správné vynucení integrity
-
možnost 4 (žádné sloupce FK s možnou hodnotou null)