mysql-Einträge nach einer stunde löschen
Grobie
- php
Hi,
ich möchte ein script schreiben, welches beim abrufen alle Zeilen löscht, die älter als eine stunde sind. Wie kann ich das anstellen? Ich denke mal, ein Feld muss eon Timestamp sein, aber irgendwie schaffe ich es nicht. kann mir bitte jemand helfen?
Grobie
Hello Grobie,
ich möchte ein script schreiben, welches beim abrufen alle Zeilen löscht, die älter als eine stunde sind. Wie kann ich das anstellen? Ich denke mal, ein Feld muss eon Timestamp sein, aber irgendwie schaffe ich es nicht. kann mir bitte jemand helfen?
Was schaffst Du denn daran nicht?
MySQL-Tabelle anlegen, sagen wir mal, die heißt LOGIN...
ID bigint
USER VarChar(20)
LOGINTIME datetime
LASTCLICK timestamp
Query-Bdingungen festlegen:
$sql = "delete from LOGIN
where unix_timestamp(LOGINTIME) < (now() - 3600)";
Und dann das Query ausführen.
Probier's mal aus...
Grüße
Tom
Hi Tom,
danke für die antwort. Mein fehler war, dass ich nicht unix_timestamp benutzt habe. dachte man kann einfach die ausgelesene zeile benutzen. allerdings klappt es immer noch nicht. er löscht jetzt immer alles, egal ob kürzer oder länger. Was muss ich tun?
Grobie
Ich habe es selber hinbekommen. allerdings mit hilfe von phpfunktionen:
$time = strtotime("-1 hour", time());
mysql_query("DELETE FROM tabelle WHERE (unix_timestamp(Zeit) < '$time')");
Danke für den Ansatz Tom. hätte man das auch irgendwie mit mysqlfunktionen machen können? bei mir hat es erst so funktioniert.
Grobie
hi,
hätte man das auch irgendwie mit mysqlfunktionen machen können?
mit den datums- und zeitfunktionen gibt es sicher auch einen weg, das zu realisieren.
http://www.mysql.de/doc/de/Date_and_time_functions.html
gruss,
wahsaga
Hello,
Danke für den Ansatz Tom. hätte man das auch irgendwie mit mysqlfunktionen machen können? bei mir hat es erst so funktioniert.
Nochmal gaaanz kurz nachgedacht und Fehler entdeckt:
$sql = "delete from LOGIN
where unix_timestamp(LOGINTIME) < (unix_timestamp(now()) - 3600)";
Die Funktion now() gibt leider den Timestamp auch als DateTime formatiert zurück. mann muss also erst wieder zurückrechnen.
Dafür kannst Du beim Eintragen einfach
insert into LOGIN set LOGINTIME=now();
schreiben.
Zu berücksichtigen wäre noch, WANN die Funktion now() evaluiert wird:
a) auf Query-Ebene
b) auf Satzebene
????
Wer weiß das genau?
Schließlich dauert es bei großen Datenbeständen schon ein paar Sekunden vom ersten bis zum letzten Datensatz
Grüße
Tom
Moin!
Nochmal gaaanz kurz nachgedacht und Fehler entdeckt:
$sql = "delete from LOGIN
where unix_timestamp(LOGINTIME) < (unix_timestamp(now()) - 3600)";Die Funktion now() gibt leider den Timestamp auch als DateTime formatiert zurück. mann muss also erst wieder zurückrechnen.
Warum so kompliziert mit der Unix-Timestamp? LOGINTIME ist vom Typ DateTime, now() gibt diesen Typ auch zurück. Fehlt noch das Subtrahieren von einer Stunde:
DATE_SUB(now(),INTERVAL 1 HOUR)
Möglicherweise gehts auch simpel so (seit MySQL 3.23):
NOW() - INTERVAL 1 HOUR
Fertig. Und wunderbar lesbar.
Ich frage mich allerdings, wozu du in deinem ersten Beispiel noch eine TIMESTAMP-Spalte eingefügt hast?
Zu berücksichtigen wäre noch, WANN die Funktion now() evaluiert wird:
Schließlich dauert es bei großen Datenbeständen schon ein paar Sekunden vom ersten bis zum letzten Datensatz
Wäre das relevant? Wenn now() zu Beginn evaluiert wird, werden alle exakt zum Startzeitpunkt zu alten Datensätze gelöscht. Wenn now() fortschreitend neu evaluiert wird, werden alle Datensätze gelöscht, die zum Löschzeitpunkt zu alt sind (und gelöscht würden, wäre nur Fall a) aktiv und erteilte man das Kommando erneut).
In beiden Fällen werden ganz grob gesehen alle Datensätze gelöscht, die älter als eine Stunde sind.
Ich tendiere aber dazu, dass now() genau einmal beim Start evaluiert wird.
- Sven Rautenberg
Hello,
Nochmal gaaanz kurz nachgedacht und Fehler entdeckt:
$sql = "delete from LOGIN
where unix_timestamp(LOGINTIME) < (unix_timestamp(now()) - 3600)";Die Funktion now() gibt leider den Timestamp auch als DateTime formatiert zurück. mann muss also erst wieder zurückrechnen.
Warum so kompliziert mit der Unix-Timestamp? LOGINTIME ist vom Typ DateTime, now() gibt diesen Typ auch zurück. Fehlt noch das Subtrahieren von einer Stunde:
Mag sein, dass das an meiner Bedienpberfläche liebt. Habe jetzt kein extra Script dafür aufgebaut, aber datetime gibt das Format 2003-10-28 12:08:45 zurück und das wird auch von now() ausgegeben.
DATE_SUB(now(),INTERVAL 1 HOUR)
Möglicherweise gehts auch simpel so (seit MySQL 3.23):
NOW() - INTERVAL 1 HOUR
Fertig. Und wunderbar lesbar.
Ich frage mich allerdings, wozu du in deinem ersten Beispiel noch eine TIMESTAMP-Spalte eingefügt hast?
Es ging nur um die Differenzierung zwischen datetime und timestamp. Timestamp wird automatisch gepfelgt und symbolisiert daher immer den letzten Zugriff auf dem Datensatz und DateTime muss explizit gesetzt werden, und eigenet sich daher z.B. für das erste Auftreten eines Ereignisses. Also z.B. nur setzen bei insert.
Zu berücksichtigen wäre noch, WANN die Funktion now() evaluiert wird:
Schließlich dauert es bei großen Datenbeständen schon ein paar Sekunden vom ersten bis zum letzten DatensatzWäre das relevant? Wenn now() zu Beginn evaluiert wird, werden alle exakt zum Startzeitpunkt zu alten Datensätze gelöscht. Wenn now() fortschreitend neu evaluiert wird, werden alle Datensätze gelöscht, die zum Löschzeitpunkt zu alt sind (und gelöscht würden, wäre nur Fall a) aktiv und erteilte man das Kommando erneut).
In beiden Fällen werden ganz grob gesehen alle Datensätze gelöscht, die älter als eine Stunde sind.
Aber auch nur _ganz_ grob!
Ich lasse die Frage, wann und wie oft now() evaluiert wird, trotzdem auf meiner Liste. Ich wüsste nur nicht, wie ich das mit meinen paar Datensätzen ausprobieren sollte.
Grüße
Tom
Moin!
Ich frage mich allerdings, wozu du in deinem ersten Beispiel noch eine TIMESTAMP-Spalte eingefügt hast?
Es ging nur um die Differenzierung zwischen datetime und timestamp. Timestamp wird automatisch gepfelgt und symbolisiert daher immer den letzten Zugriff auf dem Datensatz und DateTime muss explizit gesetzt werden, und eigenet sich daher z.B. für das erste Auftreten eines Ereignisses. Also z.B. nur setzen bei insert.
Nö. Die _erste_ Timestamp-Spalte eines Datensatzes wird automatisch mit aktualisiert, wenn der Datensatz _geändert_ wird. Natürlich kann man die Spalte auch explizit setzen, oder mit NOW() befüllen.
Mit anderen Worten: Es ist kein Problem, in einem Datensatz zwei Timestamps zu haben, die genau das machen, was deine DATETIME/TIMESTAMP-Variante auch macht. Man kann darüber streiten, welche Variante eleganter ist.
In beiden Fällen werden ganz grob gesehen alle Datensätze gelöscht, die älter als eine Stunde sind.
Aber auch nur _ganz_ grob!
Jedenfalls werden keine Datensätze gelöscht, die jünger als eine Stunde sind. :)
- Sven Rautenberg
Hello,
Nö. Die _erste_ Timestamp-Spalte eines Datensatzes wird automatisch mit aktualisiert, wenn der Datensatz _geändert_ wird. Natürlich kann man die Spalte auch explizit setzen, oder mit NOW() befüllen.
Das ist interessant. Nur die ERSTE? Ist das verbrieft? Wo ist das festgelegt? Wie ist das bei anderen Datenbanken?
Jedenfalls werden keine Datensätze gelöscht, die jünger als eine Stunde sind. :)
Dickkopp ;-))
Grüße
Tom
Moin!
Das ist interessant. Nur die ERSTE? Ist das verbrieft? Wo ist das festgelegt?
Ja, ist verbrieft in der MySQL-Doku und festgelegt im MySQL-Programmcode. :)
http://www.mysql.de/doc/de/DATETIME.html
Wie ist das bei anderen Datenbanken?
Keine Ahnung. Das sind andere Datenbanken, die müssen nicht mal zwingend einen Timestamp-Datentyp haben.
- Sven Rautenberg