PHP Vermeidung doppelter Einträge mit SQL

lordg2009

Lt. Commander
Registriert
Apr. 2009
Beiträge
1.552
Hi,

ich habe einen kleinen Chat programmiert. In seltenen Fällen kommt es vor, dass eine nachricht kurz hintereinander mehrmals abgeschickt wird. Dann liegt eine Sekunde, oder aber keine dazwischen. Das möchte ich verhindern, am besten auf dem Level SQL. Die Tabelle besteht aus
Code:
 chatID, date_create, content, userID

Ich habe mir das so überlegt. Ich füge noch eine Spalte hinzu und berechne eine MD5 Summe mit
Code:
MD5(CONCAT(content, userID))
Jetzt ist es ja manchmal gewünscht, dass eine Nachricht zweimal geschickt wird, aber eben bestimmt nicht in 10 Sekunden. Daher suche ich einen SQL Befehl nach dem Moto:
Code:
INSERT IF TIME_TO_SEC(TIMEDIFF(date_create, NOW()))>10
Dabei sollen natürlich nur jene Zeilen geprüft werden, welche die gleiche md5 checksum haben wie der neue chateintrag.

Geht sowas?

Vielen Dank für eure Hilfe
 
Das was du suchst nennt sich Trigger.

Eine extra Spalte einzuziehen die Hashsummen berechnet muss nicht die beste Lösung sein. Ein Index auf auf die Spalte mit den Nachrichten arbeitet bei vielen DBS sowieso mit Hashes und all zu oft kommt da MD5 zum Einsatz. Wobei zu erwarten ist, dass das DBS über seinen Index schneller arbeitet als alles was du (oder ich) hinbekommen.

Eine Sinnvolle Abfrage würde aber wohl zuerst auf die Zeit selektieren und erst danach auf die Hashes der Strings. Wobei je nach Umfang es sinnvoll sein könnte die Strings nicht zu Hashen sondern direkt zu vergleichen, nachdem die Auswahl an Nachrichten über die Slektion nach Zeit ausreichend verkleinert wurde.
 
Lass den Client eine ID erzeugen (und die in eine UNIQUE(ID,userid) rein), dann sollte das nicht mehr vorkommen.
Das mit dem MD5 ist eine schlechte Lösung, weil wenn ich Ok, Ok, Ok schreibe, geht das nicht, obwohl ich es bewusst wollte (und innerhalb 10 s die gleiche Nachricht ist sehr wohl plausibel).
 
Hancock schrieb:
Lass den Client eine ID erzeugen (und die in eine UNIQUE(ID,userid) rein), dann sollte das nicht mehr vorkommen.
Das als Erstes bzw. besser serverseitig hashen und für solche DB-Inserts gibts auch Unique Keys in Verbindung mit INSERT INTO ... ON DUPLICATE KEY UPDATE ... oder auch INSERT IGNORE. Dann gibts keine doppelten Einträge, weil die entsprechende ID vom Client bereits hinterlegt ist und die Daten somit nur geupdated werden oder der Query nicht fehlschlägt.
 
Wie wollt ihr eine Unique ID erzeugen, die eine Dopplung von Einträgen im gleitendem Bereich einiger Sekunden abdeckt?
 
Ich denke, es wäre sinnvoller, die Arbeit in den Client zu investieren, dass dieser Nachrichten nicht doppelt verschickt.
Der Server hat ja gar keine Möglichkeit zu unterscheiden, ob eine Nachricht mit demselben Inhalt wie die vorige, absichtlich vom User geschickt wurde oder wegen eines Fehlers des Clients doppelt geschickt wurde.
 
Es wäre definitiv sinnvoller, am Client zu arbeiten. So schaffst du nur ein workaround, beseitigst den eigentlichen "Fehler" aber nicht.

Spam-Counter einbauen, Strings vor dem abschicken prüfen, geeignete Regeln aufstellen etc pp
 
Zuletzt bearbeitet:
Wenn der Client Fehler macht und Dinge mehrfach schickt, dann musst du natürlich den Client fixen*. Ich glaube, dass keiner der Tippgeber hier auf dem Schirm hatte, dass die Clientseite Fehler macht und unter deiner Kontrolle ist. In diesem Falle wäre der Tipp natürlich, den Client zu fixen. Dein Anfangspost liest sich aber einfach so, als wolltest du Fehler Serverseitig abfangen und entsprechend fallen die Tips aus. Wobei es eben sinnvoll ist fehlerhafte Daten mit dem System abzufangen, welches auf Datenverarbeitung spezialisiert ist, also die Datenbank.


Ansonsten ein Prinzip bei der Entwicklung von Client - Server Architekturen ist, dass der Server nie dem Clienten trauen sollte.


Edit
*Fehler sollte man immer da fixen wo sie auftreten, wie amokkx schon sagt.
 
Zurück
Oben