Hihu
Ich habe eine Konzeptionelle Frage. Also ich habe ein Programm geschrieben das über mehrere Tabellen INSERTS macht. Zum Beispiel INSERT into data irgendwelche Values und danach insert into data2 wo es einen fremdschlüssel benutzt nähmlich den letzen eingetrage id bei der ersten tabelle. alles schön und gut solange die applikation localhost ist. aber im internet funken mir andere leute herein.
Kurz:
Das PROBLEM ist also das ich nicht einfach den letzen PK einer Tabelle (max) nehmen kann und diesen beim nächsten insert als Fremdschlüssel verwenden. was ist wenn jemand dazwischenfunkt?
Gibt es da irgendwelche Methoden um das zu verhindern
SPRICH: gewährleisten das der nächste insert tatsächlich die id des vorherigen nimmt (als FK)
oder inserts über 2 tabellen?
Hatt jemand irgendwelche stichworte dazu oder methoden in die ich mich einlesen kann?
danke für die antworten^^
Ankündigung
Einklappen
Keine Ankündigung bisher.
Insert foreign key
Einklappen
Neue Werbung 2019
Einklappen
X
-
Das ist keine Frage der Vorliebe. Und Transaktionen brauche ich dafür auch nicht. Timestamps sind schlicht überflüssig und bieten keinen Sicherheitsgewinn. Im Gegenteil. Auf diese Weise kann ich sehr wohl auch doppelte Schlüssel erzeugen. Der Timestamp macht es lediglich etwas unwahrscheinlicher.
Wenn schon ein so kurzer Zeitraum wie in deinem Skript zu erahnen ist ausreicht um einen doppelten Schlüssel zu erzeugen, dann wirst du auch praktisch immer den gleichen Zeitstempel dabei haben.
Du kannst das ja für deinen Privatspass so machen, aber empfehle anderen so einen Schwachsinn nicht.
-
Ne sorry, die letzten drei Beiträge von dir in diesem Forum glänzen nur so von Inkompetenz.
Was bitteschön ist komplizierter an einer Transaktion als einer zusätzlichen Tabelle und eigenen Inkrementen und eigener Implementation con Transaktion?
Einen Kommentar schreiben:
-
Ein Gast antworteteIch hab ja nicht gesagt, dass eine, durch mysql selbst gesetze, id schlecht ist.Zitat von rkr Beitrag anzeigenWozu gibt es dann autoincrement-keys*?
* heissen in anderen Datenbanken möglicherweise anders :P
habe lediglich empfohlen, durch ein timestamp, die umständliche wege der transaktion zu umgehen.
punkt
wenn dein persönliches empfinden die transaktion vorzieht. ist das eben so.
ich ess gern Apfel und trink zirtone
Einen Kommentar schreiben:
-
Wozu gibt es dann autoincrement-keys*?
* heissen in anderen Datenbanken möglicherweise anders :P
Einen Kommentar schreiben:
-
Ein Gast antworteteZitat von ChristianK Beitrag anzeigenJa schön. Oder du verwendest Transaktionen. Das wäre der korrekte Weg.VSCode:-- start a new transaction start transaction; -- get latest order number select @orderNumber := max(orderNUmber) from orders; -- set new order number set @orderNumber = @orderNumber + 1; -- insert a new order for customer 145 insert into orders(orderNumber, orderDate, requiredDate, shippedDate, status, customerNumber) values(@orderNumber, now(), date_add(now(), INTERVAL 5 DAY), date_add(now(), INTERVAL 2 DAY), 'In Process', 145); -- insert 2 order line items insert into orderdetails(orderNumber, productCode, quantityOrdered, priceEach, orderLineNumber) values(@orderNumber,'S18_1749', 30, '136', 1), (@orderNumber,'S18_2248', 50, '55.09', 2); -- commit changes commit; -- get the new inserted order select * from orders a inner join orderdetails b on a.ordernumber = b.ordernumber where a.ordernumber = @ordernumber;
SQL erweitern
, $timestampCode:WHERE timestamp = ' . $timestamp .'
Einen Kommentar schreiben:
-
Ja schön. Oder du verwendest Transaktionen. Das wäre der korrekte Weg.
Einen Kommentar schreiben:
-
Ein Gast antworteteich hab die Erfahrung gemacht, wenn zeitgleich mehr als ein Mitarbeiter INSERT verursachen kann
das mit Timestamp's zu versehen und expleziet diesen timestamp in die WHERE Klausel mit einbringen.
Sprich eine extra Spalte " TIME_of_CREAT "
Hat mir zum einen viel CODE gespart und ich hatte damit immer ein eindeutigen SELECT
vor, wärend und nach dem INSERT
Egal wieviel USER gleichzeitig INSERT`s durchführen.
Einen Kommentar schreiben:
-
Klar:Zitat von rkr Beitrag anzeigenKann ich in diesem wCTE-Statement mehr als ein Insert verbauen? Wie sähe das dann ungefähr aus?
aktueller Stand:
Nun 1 Befehl und der neue Stand:Code:test=# select * from person; id | name ----+------ (0 rows) test=*# select * from phone ; p_id | nummer ------+-------- (0 rows) test=*# select * from mail ; p_id | mail ------+------ (0 rows) test=*# select currval('person_id_seq'); currval --------- 3 (1 row)
Code:test=*# with p as (insert into person (name) values ('person1') returning id), ph as (insert into phone (select p.id, 'nummer1' from p union select p.id, 'nummer2' from p)), m as (insert into mail (select id, 'mail1' from p union all select id, 'mail2' from p)) select 'habe alles fertig'; ?column? ------------------- habe alles fertig (1 row) test=*# select * from person; id | name ----+--------- 4 | person1 (1 row) test=*# select * from phone ; p_id | nummer ------+--------- 4 | nummer1 4 | nummer2 (2 rows) test=*# select * from mail ; p_id | mail ------+------- 4 | mail1 4 | mail2 (2 rows)
Einen Kommentar schreiben:
-
Kann ich in diesem wCTE-Statement mehr als ein Insert verbauen? Wie sähe das dann ungefähr aus?
Einen Kommentar schreiben:
-
Die Doku http://www.postgresql.org/docs/9.3/s...-sequence.html und ein kleines Beispiel für wCTE:Zitat von rkr Beitrag anzeigen@akretschma
Kannst du currval() und wCTE jeweils mit einer sinnvollen Ressource verlinken?
Ich nenne NIRGENDS die ID und schicke nur EIN Statement an den Server. Das ganze ist ausbaufähig auch auf mehr als nur einen Datensatz, der in Slave reinkommen soll, beispielsweise. Insbesondere Masseninserts können davon deutlich profitieren, spart Zeit.Code:test=# create table master (id serial primary key, val text); CREATE TABLE test=*# create table slave(master_id int references master, val text); CREATE TABLE test=*# with foo as (insert into master (val) values ('master 1') returning id) insert into slave select foo.id, 'slave 1' from foo; INSERT 0 1 test=*# select * from master; id | val ----+---------- 1 | master 1 (1 row) test=*# select * from slave; master_id | val -----------+--------- 1 | slave 1 (1 row)
Einen Kommentar schreiben:
-
@akretschma
Kannst du currval() und wCTE jeweils mit einer sinnvollen Ressource verlinken?
Einen Kommentar schreiben:
-
Welche DB? In PostgreSQL kannst Du currval() nutzen oder gleich wCTE einsetzen, dann sind Deine 2 oder mehr Inserts nur 1 (EIN!) Befehl. MySQL hat last_insert_id() oder so ähnlich. Schau in die Doku. Max() jedenfalls ist prinzipiell falsch.Zitat von megaprogrammer Beitrag anzeigen
Hatt jemand irgendwelche stichworte dazu oder methoden in die ich mich einlesen kann?
danke für die antworten^^
Einen Kommentar schreiben:

Einen Kommentar schreiben: