Mysql
 sql >> Database >  >> RDS >> Mysql

Progettazione database MySQL. Inserimento di righe nelle tabelle 1to1.

Farò di questa una risposta poiché ritengo che questo sia un difetto di progettazione.

Innanzitutto, se le due tabelle sono in vero 1:1 relazione, perché non hai solo un tavolo?

Secondo, se non è un vero 1:1 relazione ma un problema di supertipo-sottotipo, non hai nemmeno bisogno di queste chiavi esterne circolari. Diciamo table1 è Employee e table2 è Customer . Ovviamente la maggior parte dei clienti non sono dipendenti (e viceversa). Ma a volte un cliente può anche essere un dipendente. Questo può essere risolto con 3 tabelle:

Person
------
id
PRIMARY KEY: id

Employee
--------
personid
lastname
firstname
... other data
PRIMARY KEY: personid
FOREIGN KEY: personid
    REFERENCES Person(id)

Customer
--------
personid
creditCardNumber
... other data
PRIMARY KEY: personid
FOREIGN KEY: personid
    REFERENCES Person(id)

Nello scenario che descrivi hai due tabelle Parent e Child con 1:N relazione. Quindi, vuoi archiviare in qualche modo il figlio con le migliori prestazioni (in base a un calcolo definito) per ogni genitore.

Funzionerebbe?:

Parent
------
id
PRIMARY KEY: id

Child
-----
id
parentid
... other data
PRIMARY KEY: id
FOREIGN KEY: parentid
    REFERENCES Parent(id)
UNIQUE KEY: (id, parentid)             --- needed for the FK below

BestChild
---------
parentid
childid
... other data
PRIMARY KEY: parentid
FOREIGN KEY: (childid, parentid)
    REFERENCES Child(id, parentid)

In questo modo, si applica l'integrità referenziale desiderata (ogni BestChild è un figlio, ogni genitore ha un solo BestChild) e non esiste un percorso circolare nei riferimenti. Il riferimento al figlio migliore è memorizzato nella tabella extra e non nel Parent tavolo.

Puoi trovare BestChild per ogni genitore unendoti a:

Parent
  JOIN BestChild
    ON Parent.id = BestChild.parentid
  JOIN Child
    ON BestChild.childid = Child.id

Inoltre, se desideri memorizzare i figli migliori per più test di prestazione (per diversi tipi di test o test in date diverse), puoi aggiungere un test campo e modifica la chiave primaria in (test, parentid) :

BestChild
---------
testid
parentid
childid
... other data
PRIMARY KEY: (testid, parentid)
FOREIGN KEY: (childid, parentid)
    REFERENCES Child(id, parentid)
FOREIGN KEY: testid
    REFERENCES Test(id)