Frage Live updating tables

  • Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Aaron3219

Aktives Mitglied
6 Oktober 2015
936
185
43
17
#1
Moin liebes Forum,

ich hoffe ihr könnt bei meinem ongoing adventure, alles mögliche mit Datenbanken zu machen, was man damit so machen kann.

Folgendes Problem:
Ich sende mit Javascript in einem 1-Sekunden-Intervall einen Ajax-Request an ein PHP-File, dass die Einträge einer Datenbank-Tabelle überprüft.
In dieser Tabelle gibt es eine Spalte (Name: "timestamp") mit der Standard-Value "CURRENT_TIMESTAMP" (von mysql).

Ich will, dass nur die Tabelleneinträge selected werden, die in der Pause zwischen diesem und dem vorherigen Intervall entstanden sind.
Ich dachte dann, dass hier würde es tun:
PHP:
"SELECT * FROM tablename WHERE timestamp > (NOW() - INTERVAL 1 SECOND)"
Das Ding ist, dass die Einträge dann manchmal nicht ausgegeben werden.

Diese 1 SECOND hab ich dann mal zu Testzwecken variiert z.B. mit 1.5 und 0.5. Dann werden aber manche Einträge zweimal ausgegeben, was für mich Sinn macht.

Aber meine Frage wäre nun, wie kriege ich das Problem in den Griff?

Edit:
Man könnte da bestimmt was zum Thema websockets sagen, aber das ist hier nicht der Punkt!
 

scbawik

Senior HTML'ler
14 Juli 2011
2.491
436
83
#2
Moin liebes Forum,

ich hoffe ihr könnt bei meinem ongoing adventure, alles mögliche mit Datenbanken zu machen, was man damit so machen kann.

Folgendes Problem:
Ich sende mit Javascript in einem 1-Sekunden-Intervall einen Ajax-Request an ein PHP-File, dass die Einträge einer Datenbank-Tabelle überprüft.
In dieser Tabelle gibt es eine Spalte (Name: "timestamp") mit der Standard-Value "CURRENT_TIMESTAMP" (von mysql).

Ich will, dass nur die Tabelleneinträge selected werden, die in der Pause zwischen diesem und dem vorherigen Intervall entstanden sind.
Ich dachte dann, dass hier würde es tun:
PHP:
"SELECT * FROM tablename WHERE timestamp > (NOW() - INTERVAL 1 SECOND)"
Das Ding ist, dass die Einträge dann manchmal nicht ausgegeben werden.

Diese 1 SECOND hab ich dann mal zu Testzwecken variiert z.B. mit 1.5 und 0.5. Dann werden aber manche Einträge zweimal ausgegeben, was für mich Sinn macht.

Aber meine Frage wäre nun, wie kriege ich das Problem in den Griff?

Edit:
Man könnte da bestimmt was zum Thema websockets sagen, aber das ist hier nicht der Punkt!
Nicht zu viel Businesslogik ins SQL verschieben ;)

Code:
api.example.com/messages?since=<timestamp_des_letzten_geladenen_eintrags>
Code:
SELECT * FROM messages WHERE timestamp > $_GET['since']
Wenn man keinen wirklichen Grund hat (Optimierung), muss man sich auch nicht wirklich mit Datenbanken beschäftigen.
In 99% der Fälle reichen einfachste SQL Statements, wenn man denn überhaupt noch direkt damit in Kontakt kommt.
 
Zuletzt bearbeitet:

Aaron3219

Aktives Mitglied
6 Oktober 2015
936
185
43
17
#3
Statt mit deiner Variante müsste es doch theoretisch auch so gehen oder nicht?
PHP:
"SELECT * FROM tablename WHERE timestamp > ".date("Y-m-d H:i:s", time() - 1);
Das tut es auf jeden Fall schon mal nicht... also gar nicht. Weniger als vorher. Jetzt wird nie ein Eintrag angezeigt.
Aber müsste es doch eigentlich oder nicht?
Ich habs gecheckt. Wenn so der Timestamp in der Tabelle aussieht:
2018-07-06 02:36:49
Sieht date("Y-m-d H:i:s", time() - 1); hier so aus:
2018-07-06 02:36:48

Warum funzt der schei* also nicht?
 
Zuletzt bearbeitet:

scbawik

Senior HTML'ler
14 Juli 2011
2.491
436
83
#4
Statt mit deiner Variante müsste es doch theoretisch auch so gehen oder nicht?
PHP:
"SELECT * FROM tablename WHERE timestamp > ".date("Y-m-d H:i:s", time() - 1);
Das tut es auf jeden Fall schon mal nicht... also gar nicht. Weniger als vorher. Jetzt wird nie ein Eintrag angezeigt.
Aber müsste es doch eigentlich oder nicht?
Ich habs gecheckt. Wenn so der Timestamp in der Tabelle aussieht:
2018-07-06 02:36:49
Sieht date("Y-m-d H:i:s", time() - 1); hier so aus:
2018-07-06 02:36:48

Warum funzt der schei* also nicht?
Nein, denn so macht man das einfach nicht!

Nochmal: Der Client sagt welche Daten er benötigt, nicht der Server.
 
Zustimmungen: Aaron3219

Aaron3219

Aktives Mitglied
6 Oktober 2015
936
185
43
17
#5
Alles klar, passt soweit.
Am Ende kam das hier dabei raus:

JavaScript:
setInterval(function() {
      var dt = new Date(Date.now() - 1000);
      var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds();

      var month = dt.getMonth() + 1;
      var day = dt.getDate();

      var output = dt.getFullYear() + '-' +
        (('' + month).length < 2 ? '0' : '') + month + '-' +
        (('' + day).length < 2 ? '0' : '') + day;


      var date = output + " " + time;
      refresh(timestamp = date);
}, 1000);
PHP:
"SELECT * FROM live_update WHERE timestamp = '".$_POST['timestamp']."'";
Funktioniert erste Sahne.
 

scbawik

Senior HTML'ler
14 Juli 2011
2.491
436
83
#6
Alles klar, passt soweit.
Am Ende kam das hier dabei raus:

JavaScript:
setInterval(function() {
      var dt = new Date(Date.now() - 1000);
      var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds();

      var month = dt.getMonth() + 1;
      var day = dt.getDate();

      var output = dt.getFullYear() + '-' +
        (('' + month).length < 2 ? '0' : '') + month + '-' +
        (('' + day).length < 2 ? '0' : '') + day;


      var date = output + " " + time;
      refresh(timestamp = date);
}, 1000);
PHP:
"SELECT * FROM live_update WHERE timestamp = '".$_POST['timestamp']."'";
Funktioniert erste Sahne.
Nich ganz was ich gemeint habe, aber wenn es funktioniert auch in Ordnung :)

Hier trotzdem noch meine Variante, ist aber auch nicht perfekt und ungetestet. Für einfachere Lesbarkeit auch mit jQuery.
Der Vorteil ist dass bei dieser Variante garantiert keine Zeilen ausgelassen bzw. übersprungen werden.
Bei dir könnte es unter gewissen Umständen dazu kommen.
JavaScript:
// lokaler data store
let rows = [];

setInterval(function () {

    // timestamp des letzten lokalen Eintrags holen
    let lastTimestamp = rows.length ? rows[rows.length - 1].timestamp : 0;

    $.ajax({
        url: 'http://api.example.com/messages?timestamp='+lastTimestamp
    }).done(function (data) {
        // neue daten zum array hinzufügen
        rows.concat(data);
    })

}, 1000);
Der Unterschied ist ganz einfach:

Du sagst dem Server "Gibt mir alle Einträge vom 07.07.2018 18:45:23". Das setzt voraus, dass die Anfragen zeitlich perfekt, ohne Zwischenfälle beim Server angelangen und auch zurückgeliefert werden.

Ich hingegen sage dem Server "Mein letzter Eintrag hat den Timestamp 07.07.2018 18:45:22, schick mir alles was danach dazu gekommen ist.".
Da ist es dann egal ob das Delta nun 1 Sekunde, 20 Sekunden oder auch 1 Stunde dauert. Mein letzter geladener Stand bleibt der gleiche.
 
Zuletzt bearbeitet: