sql >> Databáze >  >> RDS >> Mysql

Je v SQL v pořádku, aby na sebe dvě tabulky odkazovaly?

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)



  1. ~/.psqlrc soubor pro DBA

  2. Proč moje levé připojení t-sql nefunguje?

  3. Jak vytvořit novou databázi po prvotní instalaci databáze Oracle 11g Express Edition?

  4. Jak získat seznam měsíců mezi 2 danými daty pomocí dotazu?