Forumuser neue topics anzeigen

eLorFiN

Erfahrenes Mitglied
Abend alle miteinander :)

Ich hätte da folgendes Problem:

Ich bin dabei, mir ein Forum zu basteln und darf dabei in die komplette Trickkiste von PHP/MySQL greifen, nun steh ich aber da, wie der Ochs vorm Berg mit folgendem Problem:

Wenn ein User sich anmeldet, soll er ein Cookie aufgedrückt bekommen, erstens weiß ich nicht so recht, was ich im Cookie außer dem Usernamen übergeben muss, da ich jederzeit auf die Datenbank zugreifen kann und zweitens, wie realisiere ich es, dem User anzuzeigen, welche Topics seit seinem letzen Besuch neue posts enthalten.
Ich habe zunächst an timestamps gedacht, also wann der user zuletzt online war und wann der letzte Post gemacht wurde, Problem dabei ist aber, wenn der User sich zuerst den neusten Post anschaut, bekommt er einen neuen timestamp ohne dass er die Posts gelesen hat, die dazwischen standen.

Oder sollte ich vielleicht in ein seperates cookie die POST-ID speichern, die der User zuletzt besichtigt hat und jedes mal wenn er einloggt die Post-IDs speichern, die er nicht gelesen hat und jedes mal das cookie überschreiben, weil ich eines davon ja wegstreichen muss?
Beispiel:
User hat zuletzt post 20 gesehen, die neuste Post id ist 24
also bekommt er gespeichert
COOKIE [21,22,23,24]
User besucht post 23, cookie eins wird überschrieben mit
COOKIE [21,22,24]
? hört sich doch verdammt sinnlos an...!

Wie sollte ich dieses Problem also lösen, bin ich zu sehr auf cookies fixiert?(cookies sind neuland für mich, hab immer versucht, sie zu umgehen)

danke im voraus :)
 
Ersteinmal versuche von Cookies wegzukommen! Denn viele haben Cookies deaktiviert und dann funktioniert dein Forum nicht.

Als nächstes würd ich den Last Login timestamp mit den timestamps der beiträge vergleichen, und alle die neuer sind markieren. Mach das blos nicht Cookie basierend. Ich arbeite zum Beispiel auf mehreren Rechner, wenn ich dann ständig "neue" Post lese die cih bereits gelesen hab würd ich nie mehr zum arbeiten kommen, bzw. das Forum meiden.

Zur Lösung mit deinem Problem:

Leg 2 Felder in der DB an: last_login login

In last_login steht der Wert, den du mit den timestamps der Beiträge vergleichst. nd in Login der aktuelle Logintimestamp. Beim nächsten Login speicherst du den Wert der in Login steht einfach in last_login und den aktuellen Timestamp in login.

In den Cookies solltest du ID speichern, mit dieser solltest du alle Datenabfragen können. Aus Performance gründen solltest du vielleicht häfige verwendete Daten noch mit hineinspeichern.

Ich hoffe ich konnte dir ein wenig helfen.
 
Oh well soweit komm ich ja auch, also dem User anzuzeigen, welche posts er verpasst hat.
Danke trotzdem...

Mir geht es eher darum, ihm anzuzeigen welche Posts er noch nicht gelesen hat und wenn er einen Post besucht, dieser Post NICHT mehr als neuer Post angezeigt wird, aber alle anderen noch nicht gesehenen.
Das kannst du dir so vorstellen, wie die leuchtenden Glühbirnen hier in der Tutorials.de Forenübersicht.

Ich werde heute meine Tabelle für die Posts anlegen, nachdem die Userdatenbank eigentlich fertig ist :)
 
Zuletzt bearbeitet:
eLorFiN hat gesagt.:
Oh well soweit komm ich ja auch, also dem User anzuzeigen, welche posts er verpasst hat.
Danke trotzdem...

Mir geht es eher darum, ihm anzuzeigen welche Posts er noch nicht gelesen hat und wenn er einen Post besucht, dieser Post NICHT mehr als neuer Post angezeigt wird, aber alle anderen noch nicht gesehenen.
Das kannst du dir so vorstellen, wie die leuchtenden Glühbirnen hier in der Tutorials.de Forenübersicht.

Ich werde heute meine Tabelle für die Posts anlegen, nachdem die Userdatenbank eigentlich fertig ist :)

Hat noch jemand eine Idee, ausser das man für jeden Thread einen Eintrag in die DB schreiben muss? Das würde nach einer Weile ja sicher ganz schön viel werden, hinzu kommen noch diverse andere Update's?
Mir fällt aber keine andere Lösung ein. :confused:

thx und byez
 
Wenn man berücksichtigen will, dass User auch an verschiedenen Rechnern arbeiten oder aus sonstigen Gründen keine Cookies will, sehe ich nur die Möglichkeit, das in der Datenbank zu speichern.
Allerdings muss man nicht für jeden Thread einen Eintrag in die DB machen, sondern für jede Kombination aus Thread und User für vom User gelesene Thread.
Wie sagg sagt könnte es bei großeren Foren oder wenn sie lange bestehen zu Performanceproblemen auf dem Server kommen.

Du hast ja im Prinzip eine m:n Beziehung zwischen Usern und Threads, nämlich User x hat Thread y gelesen.
m:n Beziehungen kannst Du in der Datenbank durch eine weitere Tabelle darstellen:

Tabelle: threadsreadbyuser
Felder:
  • UserID
  • ThreadID
Die Tabelle hat einen zusammengesetzten Primärschlüssel aus den beiden Feldern. Damit sollten doppelte Einträge verhindert sein.

Wenn ein User einen Thread aufruft schreibst Du das Paar aus UserID und ThreadID in die Tabelle.
Wenn ein User in dem Thread einen Post macht, löscht Du alle Paare, in denen die ThreadID auftaucht, außer der Zeile, in der die UserID des postenden Users steht.

Wenn Du zusätzlich noch mit einem TIMESTAMP den Zeitpunkt des Besuchs des Threads durch einen User in der Tabelle speicherst, lassen sich bestimmt noch weiterreichende Darstellungs- bzw. Selektionsmöglichkeiten realisieren.

Abfragen auf "noch nicht gelesen" kann man so ein Konstrukt mit einem LEFT JOIN und Prüfung auf NULL der entsprechenden Felder.
Ich versuche mich jetzt mal hier im Editor an so einem Query, also nicht meckern, wenn da Syntaxfehler drin sind:
Code:
SELECT 
thread.ID, 
thread.weitereThreadFelder, 
thread.nochMehrThreadFelder 
FROM thread LEFT JOIN threadsreadbyuser 
ON (thread.ID=threadsreadbyuser.ThreadID 
AND 
threadsreadbyuser.UserID=[IDdesAngemeldetenUsers])
[evtl. weitere JOINS, um zum Beispiel den Usernamen des letzten Posts auszulesen]
WHERE threadsreadbyuser.ThreadID IS NULL
Ein Hilfsfeld gelesenStatus ist zwar unnötig in der Tabelle, bietet unter Umständen aber weitere Möglichkeiten, wie zum Beipiel eine Kennzeichnung, wie "der Thread interessiert mich nicht".

Die Nachteile sind, wie erwähnt, eine relativ große Datenmenge in der Tabelle bei mehr Usern und vielen Threads. Wie schlimm der Performancenachteil ist müßte man sicher mal ermitteln, aber ich bin mir relativ sicher, dass ein Forum, wie Tutorials.de, daran bezüglich Serverlast zu Grunde gehen würde.
Außerdem bleiben unterstützende Darstellungen für nicht angemeldete Benutzer unberücksichtigt. Das ließe sich aber ohnehin wohl nur über Kekse lösen.

Ich nutze so ein Konstrukt für ein mäßig frequentiertes privates Forum mit ca. 10 Benutzern, wovon 4 regelmäßig aktiv sind. Das ist auch nach ca. 3 Jahren auf einem 350MHz Server nicht spürbar langsamer, als am ersten Tag.
Man muss allerdings berücksichtigen, dass die Tabelle im schlimmsten Fall "Anzahl User mal Anzahl Threads" Zeilen hat.

Vielleicht konnte ich Dir damit ja eine Anregung geben.

Gruß hpvw
 
Hi,

Danke für deine Antwort, so in der Art hatte ich mir das gestern auch vorgestellt. Nur das ich bei mir noch einen Timestamp mit rein machen möchte.
Anhand dieses Timestamps sollen dann nur die Threads als neu markiert werden, die zwischen dem letzten login und "Jetzt" liegen. Wird ein Thread gelesen wird ein Eintrag in die DB geschrieben und der Thread somit als gelesen markiert.
Postet er selbst oder ein anderer User etwas in diesem Thread wird der Eintrag wieder gelöscht.

Alle Threads die vor dem letzten Login-Datum liegen werden ebenfalls als gelesen markiert, somit dürfte ich nicht auf die Summe von "User mal Threads" kommen.
Bei jetzt schon über 200 Usern und ein paar hundert Einträgen wäre das sicher ein bischen sehr viel.
Ansonsten nimmt sich dein Vorschlag nicht viel von meiner Idee, somit eine gute Bestätigung dafür, dass es gehen muss und ich das nicht umsonst mache. ^^
Aber dass das in solchen großen Foren wie hier auch so gemacht wird kann ich mir eben auch nicht so recht vorstellen, die DB müsste ja tausende von Einträgen haben. :confused:

Aber der zusammengesetzte Primärschlüssel ist eine gute Idee, werde ich bei mir auch machen. :)

Dankö, werd ich dann mal Anfangen das Forum umzuschreiben und hier und dort noch ein paar Query's einfügen. (Wieviele DB-Zugriffe so einem Forum braucht denkt man gar nicht ;))


byebyez
 
Zuletzt bearbeitet:
Hast Du auch so eine "eingeloggt bleiben" Funktion, wie hier bei Tutorials?
Wenn ja, würde mich mal interessieren, wie Du zwischen neuem einloggen, sprich "neu den Browser aufmachen", und einfach einem Link, zum Beipiel auf der Startseite einen Klick auf "neue Beiträge" unterscheidest.
 
Ja, habe ich.
Aber die login-Funktion wird nur aufgerufen, wenn keine Session besteht.
Und nur beim Login wird das Logindatum upgedatet, der letzte klick wird widerrum in einem anderem Feld gespeichert.

byez
 
Nur, um das nochmal zusammenzufassen und zum besseren Verständnis:
Also könntest Du in der Login-Funktion die Tabelle für den entsprechenden User bereinigen.
Damit bleibt sie wohl ausreichend klein und nur für die aktive Session eines Users werden die gelesenen Beiträge explizit markiert. Die Beiträge, die vor dem aktuellen Login liegen werden über den Zeitstempel als gelesen (bzw. bekannt, er muss sie ja nicht gelesen haben) markiert.
Das Query wird dann sicher etwas umfangreicher. Aber das ist wohl eine (für den User) nutzbare und (für den Server) praktikable Lösung.
Hauptsache man bekommt das noch in ein Query und muss nicht für jeden (potentiell interassenten) Thread einzeln noch ein weiteres starten, dann wäre der Server wieder unnötig belastet.
Theoretisch ist ja für jede Auflistung oder Tabelle, die am Ende in der HTML-Seite gezeigt wird, nur ein Query nötig.

Danke für den Tip mit dem Login, habe wieder mal was gelernt bzw. bin auf neue Ideen gekommen.

Gruß hpvw
 
Der Query wird wirklich sehr lang, und damit meine ich sehr lang. :D
Ich greife mitlerweile auf 5 Tabellen zu und der reine Query ist schon auf sage und schreibe 895 Zeichen angewachsen (mit Zeilenumbruch geht er über 9 Zeilen ^^), und er wird noch ein bischen länger werden.
Dort noch durchzusehen erfordert höchste Konzentration, sonst vergisst man ein was und darf alles wieder neu machen.

Aber was soll's, Spass muss sein. :)


byez und viel Spass.
 
Zuletzt bearbeitet:
Zurück