Grobie: mysql-Einträge nach einer stunde löschen

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

  1. 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

    1. 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

      1. 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

        1. 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

        2. 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

          1. 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

            --
            "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
            (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
            1. 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 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.

              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

              1. 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

                --
                "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
                (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
                1. 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

                  1. 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

                    --
                    "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
                    (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)