MySQL: Wie erstelle ich einen Foreign Key ohne ID überschneidung

Wolly300

Lieutenant
Registriert
Mai 2014
Beiträge
514
Hallo zusammen,

ich habe für mein Beispiel Tabelle A und B. Beide Tabellen haben die Spalte ID, die PRIMARY KEY und AUTO_INCREMENT Feld ist.

Ich erstelle also einen Eintrag in Tabelle A und möchte jetzt mit 3 Einträgen in Tabelle B auf den Eintrag in Tabelle A verweisen.
Wie bekomme ich am sichersten nachdem erstellen des Eintrags in A die ID ?

Soetwas wie "SELECT max(id) FROM tablename" nehme ich nicht, weil es natürlich zwischenzeitlich passieren kann, dass ein 2 Eintrag in Tabelle A erstellt wurde und auf diesen jetzt verwiesen wird.

Auch will ich keinen SELECT mit allen INSERT Paramtern machen, weil natürlich zwischenzeitlich ein 2. INSERT mit exakt den gleichen Feldern nur mit einer anderen ID erstellt worden sein kann.

Wie wird das also im professionellen Umfeld gemacht, um hier sicher zu gehen ?

Grüße

Wolly
 
Wenn das so kritisch bei Dir ist, würde ich die erste Tabelle "LOCKEN", bis die Daten in die 2. Tabelle geschrieben worden sind. Oder halt GUID ..
 
Naja, prinzipiell kann man das natürlich auch einem ORM wie Entity Framework, (n)hibernate, o.ä. überlassen. Dann hat man weitestgehend nichts mehr mit der Datenbank im eigentlichen Sinne tun, weil man aus Programmierersicht nur Objekte ablegt und abruft.
 
Wolly300 schrieb:
Das ist ja genauso unsicher wie "SELECT max(id) FROM tablename"
Das ist nicht ganz korrekt. LAST_INSERT_ID liefert die letzte ID die über eine Connection erzeugt wurde. Wenn andere Clients/Connections IDs erzeugen beeinflusst das nicht Deine Session:

https://dev.mysql.com/doc/refman/8.0/en/getting-unique-id.html

For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.
 
Man sollte nur einmal schauen, falls man eine Abstraktion verwendet (z.B. über PHP auf die DB zugreift), inwiefern diese neue Verbindungen aufbaut.

Stack Overflow Thread dazu
 
Zuletzt bearbeitet:
das ist ja auch schon komisch das es sein kann das "gleiche" objekt nochmal in der Datenbank abzulegen unter anderer id.
deswegen wie schon gesagt eine guid verwenden die dir erlaubt jedes Objekt eindeutig zu identifizieren und wiederzufinden. nach der kannst du dann filtern und musst dich nicht auf spezifika von last abfragen verlassen.
 
oder ne sequence über die du per nextval beim record anlegen die nächste freie eindeutige id bekommst z.b.

CREATE SEQUENCE mysequence;

INSERT INTO mytable (id, value) VALUES (NEXTVAL('mysequence'), 1);
 
Ich bin mir aus deiner Beschreibung jetzt nicht ganz sicher:
Hast du ein Programm, dass dir die Datenbank füllt oder arbeitest du auf DB-Ebene?

Ich glaube ersteres, aber bei letzterem und wenn du z.B. Änderungen an Datensätzen in der Tabelle o.ä. loggen willst, hättest du die Möglichkeit mit Triggern zu arbeiten.

Für ersteres sollte es, wie schon erwähnt, ausreichend sein, gleich nach dem Insert LAST_INSERT_ID() abzufragen und in eine Variabel zu packen.
 
AW4 schrieb:
Für ersteres sollte es, wie schon erwähnt, ausreichend sein, gleich nach dem Insert LAST_INSERT_ID() abzufragen und in eine Variabel zu packen.
Falls ein MVC Framework / ORM o.ä. verwendet wird ist es ggf. ziemlich einfach.
So etwas wie
Code:
myitem = Item.create name: "Shoe", size: 34
myWarehouse.add(myItem)
Ist ja durchaus üblich.
 
Zurück
Oben