stefankittel
Goto Top

Eindeutige ID in PHP (MySQL) erzeugen?

Hallo,

ich möchte gerne sicherheitstechnisch unkritische Einträge in einer Datenbank speichern.
Jeder Datensatz soll eine eindeutige ID haben.

Jetzt bin ich ein bischen genervt, dass das scheinbar nirgendwo vorgesehen ist.

Ich habe genügend Beispiele mit denen sich IDs erzeugen lassen wo es 100 mal wahrscheinlicher ist im Lotto zu gewinnen, aber nicht Null.

1) Autoincrement Wert einer MySQL Datenbank. Der ist definitiv eindeutig.
Aber ich bekomme die IDs meinen Datensatzes ja nur über mysql_insert_id erhalten. Also die ID des zuletzt angefügten Eintrages.
Bei einem Multithreadingsystem kann es aber doch passieren, das zwischen hinzufügen und auslesen woanders noch ein Eintrag hinzugefügt wird.

2) PHP Unique basiert auf der Zeit in Mikrosekunden. Auch da ist es nicht unmöglich, dass dieses doppelt vorkommt.

PCNamen des Clients, Laufzeit des Clients: Alles ist nicht eindeutig.

Die Kombination aus PCNamen des Clients, Laufzeit des Clients, LAN IP, WAN IP, Name des Benutzers, PHP Unique
Alles schon recht unwahrscheinlich, aber nicht Null....

Ist alles theoretisch, aber warum kann php unique nicht über eine CriticalSection nach dem Erzeugen einfach eine Mikrosekunde warten?
Gibt es sowas?

Danke

Stefan

PS: Eine CriticalSection ist eine Funktion die dafür sorgt, dass eine Routine nur einmal zur Zeit aufgerufen werden kann.

Content-Key: 160179

Url: https://administrator.de/contentid/160179

Printed on: April 23, 2024 at 08:04 o'clock

Member: maretz
maretz Feb 05, 2011 at 07:54:07 (UTC)
Goto Top
Naja - du kannst ja schon einiges machen.

Entweder generierst du dir im Programm eine eindeutige ID (z.B. Millisekunden und die PID des Threads, einer eindeutigen Thread-ID o.ä.). Oder du nutzt z.B. Transaktionen. Diese kann ja z.B. beinhalten:

start-transaktion
trage Datensatz in Tabelle 1 ein
lese ID des Datensatzes nochmal aus
trage Datensatz inkl. ID in Tabelle 2 ein
ende-transaktion

Da darf in der Zeit niemand an der Tabelle drehen - das verhindert dein DBMS....
Member: StefanKittel
StefanKittel Feb 05, 2011 at 09:23:25 (UTC)
Goto Top
Zitat von @maretz:
Da darf in der Zeit niemand an der Tabelle drehen - das verhindert dein DBMS....
Moin, und das ist mein Problem face-smile
Es sind mehrere Computer in verschiedenen Netzwerken die keine Verbindung untereinander haben.
Einzige zentrale Instanz ist ein Debian Webserver mit PHP, MySQL (nur via PHP) und FTP.
Es besteht die, wenn auch sehr sehr geringe Möglichkeit, dass zwei PCs mit dem gleichen Namen zur gleichen Uhrzeit einen Datensazu anlegen möchten.

Ich werde es wohl über FTP lösen. Datei öffnen mit Share Deny all (Also Zugriff für alle anderen Verweigern).

Ich findes es nur komisch, dass die Unique Funktion bei PHP das nicht kann und dass es beim MySQL Keine Funktion gibt welche einen Datensatz anlegt und dessen ID zurückgibt.
Ich hatte gehoffe ich wäre nur zu blind.

Stefan
Member: Dani
Dani Feb 05, 2011 at 12:52:11 (UTC)
Goto Top
Hi Stefan,
du hast die Möglichkeit MySQL-Tabellen für andere Zugriffe zu sperren/entsperren bis der Thread fertig ist. Handbuch.


Grüße,
Dani
Member: StefanKittel
StefanKittel Feb 05, 2011 at 12:54:50 (UTC)
Goto Top
Hallo Dani,
perfekt.

Danke!

Stefan
Member: dog
dog Feb 05, 2011 at 13:13:49 (UTC)
Goto Top
PHP ist kein Multithreading-System und mysql_insert_id bezieht sich immer auf das letzte INSERT der aktuellen Verbindung.
Auch wenn zwischen deinem Insert noch 100 weitere Zeilen von anderen Benutzern kommen gibt es da kein Problem.

The value of mysql_insert_id() is affected only by statements issued within the current client connection. It is not affected by statements issued by other clients.

http://dev.mysql.com/doc/refman/5.0/es/mysql-insert-id.html
Member: StefanKittel
StefanKittel Feb 05, 2011 at 13:58:38 (UTC)
Goto Top
Hallo dog,
schick, in meiner doku stand das nicht.
Es kam mir gleich so komisch vor, denn auf hochfrequentierten Systemen (Server von Amazon z.B.) würde das sonst ja gar nicht funktionieren.
Danke
Stefan