Mysql
 sql >> Base de données >  >> RDS >> Mysql

Conception de la base de données MySQL. Insertion de lignes dans des tableaux 1to1.

Je vais en faire une réponse car je pense qu'il s'agit d'un défaut de conception.

Premièrement, si les deux tables sont en vrai 1:1 relation, pourquoi n'avez-vous pas qu'une seule table ?

Deuxièmement, si ce n'est pas un vrai 1:1 relation mais un problème de supertype-sous-type, vous n'avez pas non plus besoin de ces clés étrangères circulaires. Disons table1 est Employee et table2 est Customer . Bien sûr, la plupart des clients ne sont pas des employés (et vice-versa). Mais parfois, un client peut aussi être un employé. Cela peut être résolu en ayant 3 tables :

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)

Dans le scénario que vous décrivez, vous avez deux tables Parent et Child ayant 1:N relation. Ensuite, vous souhaitez stocker d'une manière ou d'une autre l'enfant le plus performant (basé sur un calcul défini) pour chaque parent.

Est-ce que ça marcherait ? :

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)

De cette façon, vous appliquez l'intégrité référentielle souhaitée (chaque BestChild est un enfant, chaque parent n'a qu'un seul BestChild) et il n'y a pas de chemin circulaire dans les références. La référence au meilleur enfant est stockée dans la table supplémentaire et non dans le Parent table.

Vous pouvez trouver BestChild pour chaque parent en rejoignant :

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

De plus, si vous souhaitez stocker les meilleurs enfants pour plusieurs tests de performance (pour différents types de tests ou des tests à différentes dates), vous pouvez ajouter un test et modifiez la clé primaire en (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)