Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Zuverlässigkeit von last_insert_id

2 views
Skip to first unread message

- -

unread,
Dec 24, 2009, 5:29:38 PM12/24/09
to
Hi,

da ich das $dbh->last_insert_id vorher noch nicht eingesetzt habe,
wollte ich mal fragen, wie zuverlässig das ist - bzw. wie zuverlässig
auch wirklich eine ID zurückgegeben wird. (also unter der
Voraussetzung, daß es generell mit meiner MySQL DB funktioniert
natürlich)

Was mich an der Beschreibung dazu stört ist einmal der Satz "Returns a
value 'identifying' the row just inserted, if possible." <- "if
possible" und in "Returns undef if the driver does not support the
method or can't determine the value." <- "or can't determine the
value".

Nunja, ich möchte die ID (auto_increment) ja haben, um in weiteren
Tabellen zu der ID noch weitere Daten abzulegen. ... aber dazu muß es
auch sicher sein, daß ich auf diese Weise die ID zurück bekomme. Und
nicht, daß Perl oder MySQL auf einmal denkt "Och, heute hab ich keine
Lust ne ID zurück zu liefern, weil ich so schon ne Menge schuften
muß" ... weil wenn das passieren würde, dann wär der kompletten
Datensatz am Ende des Scripts ungültig und das kann ich in meinem Fall
nicht gebrauchen.


Was ich mich weiterhin frage - in der Beschreibung gibt es folgenden
Satz:

"If the underlying database offers nothing better, then some drivers
may attempt to implement this method by executing "select max($field)
from $table". Drivers using any approach like this should issue a
warning if AutoCommit is true because it is generally unsafe - another
process may have modified the table between your insert and the
select. For situations where you know it is safe, such as when you
have locked the table, you can silence the warning by passing Warn =>
0 in \%attr."

Da wird geschrieben, daß die Variante max($field) unsafe ist, weil
eben ein anderer Insert eventuell auch schon was eingefügt hat. Und
für diesen Fall lieber einen lock machen sollte.

Ist denn das last_insert_id safe ? - weil man muß das ja auch separat
von $dbh abfragen und somit könnte doch dann zwischen dem execute oder
do und dann dieser Abfrage sich auch schon was in der Tabelle getan
haben (zumindestens theoretisch) - weil es wird ja laut Beschreibung
die _letzte_ ID zurück gegeben. Also müßte ich doch auch vor dem
Insert ein lock machen ?


Daher die Frage - wie zuverlässig etc. funktioniert das
last_insert_id ?

MFG
Christoph


Message has been deleted

Peter J. Holzer

unread,
Dec 26, 2009, 2:49:48 PM12/26/09
to
On 2009-12-25 11:55, Ralf D�blitz <doeb...@doeblitz.net> wrote:
> - - <ch_p...@gmx.de> schrieb:

>> da ich das $dbh->last_insert_id vorher noch nicht eingesetzt habe,
>> wollte ich mal fragen, wie zuverl�ssig das ist - bzw. wie zuverl�ssig
>> auch wirklich eine ID zur�ckgegeben wird.
>
> Das h�ngt von der benutzten Datenbank und evtl. auch ihrer Konfiguration
> ab.
>
>> (also unter der
>> Voraussetzung, da� es generell mit meiner MySQL DB funktioniert
>> nat�rlich)
>
> MySQL oder eine Datenbank? SCNR. Warum nimmst du nicht etwas richtiges
> wie z.B. PostgreSQL?

Thema verfehlt. Setzen, f�nf! ;-)

MySQL kennt last_insert_id (es w�rde mich nicht wundern, wenn MySQL der
Grund w�re, warum es diese Funktion in DBI �berhaupt gibt). Andere
Datenbanken wie z.B. Oracle kennen es nicht ((Oracle-)Sequences
funktionieren ganz anders als auto-increment-Spalten - allein das
Konzept der Funktion last_insert_id w�re in Oracle widersinnig). Wieder
andere nehmen eine Zwitterstellung ein, wo der Treiber (z.B. DBD::Pg)
last_insert_id halbwegs brauchbar emuliert.

Im Zweifelsfall w�rde ich mich eher bei DBD::mysql darauf verlassen,
dass last_insert_id das gew�nschte tut als bei DBD::Pg, schlicht und
einfach, weil es bei ersterem eine grundlegende Funktion des RDBMS ist,
bei letzterem aber eine relativ komplexe und m�glicherweise auch nicht
besonders h�ufig gebrauchte Funktion im Treiber.


> Ansonsten mu�t du eben daf�r sorgen, da� du ein RDBMS nimmst, da� so
> etwas zuverl�ssig unterst�tzt. Bei MySQL bedeutet das, da� du die Kiste
> durch Wahl geeigneter Tabellentypen auf die �bliche SQL-Semantik trimmst
> (voller ACID-Support)

Nein, last_insert_id hat (by MySQL) �berhaupt nichts mit ACID zu tun.

hp

Message has been deleted

Peter J. Holzer

unread,
Dec 28, 2009, 7:32:19 AM12/28/09
to
On 2009-12-27 10:10, Ralf D�blitz <doeb...@doeblitz.net> wrote:
> Peter J. Holzer <hjp-u...@hjp.at> schrieb:
> [...]

>> Nein, last_insert_id hat (by MySQL) �berhaupt nichts mit ACID zu tun.
>
> Und du bist sicher, da� das bei MySQL ohne ACID bei simultanen Inserts
> korrekt funktioniert?

Ja, weil es bei MyISAM keine simultanen Inserts gibt. Schreiboperationen
auf Tabellen werden immer serialisiert (und in den meisten F�llen
blockiert eine Schreib-Operation auch Lese-Operationen, mit den
bekannten Folgen f�r die Performance). Aber auch ohne diese
Holzhammermethode w�re es nicht so schwierig, sich die Id(s) zu merken,
die man eingef�gt hat.

> IIRC war doch gerade fehlende Isolation lange Zeit das Hauptproblem
> von MySQL,

Kommt darauf an, f�r wen. Manchen Leuten ist das vollkommen egal, die
hat mehr die schlechte Performance bei schreibintensiven Anwendungen
gest�rt.


> da w�rde es mich schon sehr �berraschen, wenn sie das
> ausgerechnet f�r so etwas unwichtiges auch ohne ACID zuverl�ssig
> hinbekommen h�tten.

Es ist trivial: Full-Table Lock, Insert-Operation durchf�hren, dabei die
erste eingef�gte Id merken, Tabelle wieder freigeben. Und es ist nicht
unwichtig - eingef�gte Daten mit einer eindeutigen Id zu versehen (die
man nachher auch kennt!) ist eine ziemlich grundlegende Operation in
fast jeder Datenbankapplikation. Das geh�rt zu den Dingen, die einfach
funktionieren m�ssen, und ohne Transaktionen ist es schwer, sowas in der
Applikation nachzubauen.

hp

0 new messages