Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Datenbankdesign. Einfügen von Zeilen in 1zu1-Tabellen.

Ich werde dies zu einer Antwort machen, da ich der Meinung bin, dass dies ein Konstruktionsfehler ist.

Erstens, wenn die beiden Tabellen im wahren 1:1 sind Beziehung, warum haben Sie nicht nur einen Tisch?

Zweitens, wenn es kein echtes 1:1 ist Beziehung, sondern ein Supertyp-Subtyp-Problem, brauchen Sie diese zirkulären Fremdschlüssel auch nicht. Sagen wir table1 ist Employee und table2 ist Customer . Natürlich sind die meisten Kunden keine Angestellten (und umgekehrt). Aber manchmal kann ein Kunde auch ein Mitarbeiter sein. Dies kann mit 3 Tabellen gelöst werden:

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)

In dem von Ihnen beschriebenen Szenario haben Sie zwei Tabellen Parent und Child mit 1:N Beziehung. Dann möchten Sie irgendwie das Kind mit der besten Leistung (basierend auf einer definierten Berechnung) für jeden Elternteil speichern.

Würde das funktionieren?:

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)

Auf diese Weise erzwingen Sie die gewünschte referentielle Integrität (jedes BestChild ist ein Child, jedes Parent hat nur ein BestChild) und es gibt keinen kreisförmigen Pfad in den Referenzen. Der Verweis auf das beste Kind wird in der Extratabelle gespeichert und nicht im Parent Tisch.

Sie können BestChild für jedes Elternteil finden, indem Sie sich anmelden:

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

Wenn Sie außerdem die besten untergeordneten Elemente für mehrere Leistungstests (für verschiedene Arten von Tests oder Tests an verschiedenen Daten) speichern möchten, können Sie einen test hinzufügen und ändern Sie den Primärschlüssel 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)