Fourm - neue/ungelesene Posts hervorheben

Guten Morgen,

ich bin gerade dabei ein Forum zu schreiben. Ich möchte es dabei realisieren, dass ein registrierter Nutzer sieht, in welechen Threads es ungelesene Posts gibt.

Ich habe mir gedacht, ich speichere beim Login in eine Session, wann der letzte Login war und vergleiche es mit den Posts. Ist der Post neuer, Treffer, ist er älter, kein Treffer.

So weit so gut.

Pro:
:arrow: Kein Speicherplatz in der Datenbank
:arrow: Wenig Code

Kontra:
:arrow: Wird die Sitzung beendet, hat er aus Systemsicht alle Posts automatisch gelesen.

Wie würdet Ihr es machen, dass der Kontrapunkt wegfällt?

Habe mir überlegt jeden gelesenen Post in einer Datenbank zu speichern, zu jedem User.

Probleme:
:arrow: 500 Posts, 100 User
:arrow: 50.000 Datenbankeinträge

Als nächstes habe ich mir die Umkehrung des ganzen überlegt. Nicht gelesene Einträge in die Datenbank. Alle einträge älter als ein Monat werden gelöscht.

Probleme (Angenommen es gibt 100 User:
:arrow: Bei jedem Post werden 100 Einträge + der des Postes vorgenommen
:arrow: id = integer (2.147.483.647), wird diese Zahl überschritten, Schicht im Schacht.

Gut kann also auch nicht sein. Weitere Überlegung: Zu jedem Thread nur einen Timestamp speichern, wann dieser zuletzt gelesen wurde. Resultat ist aber eigentlich genau dasselbe wie bei meiner ersten Überlegung, wo die Datenbank ins Spiel kommt.

Wie wird sowas in den modernen Foren umgesetzt? Wie würdet ihr das ganze machen? War vielleicht eine Lösungmöglichkeit von mir doch garnicht mal so falsch?

Vielen Dank für eure Hilfe :razz:

Ich wuerds so machen:

Speicher zu jedem Thread eine Liste mit Usern, die diesen Thread seit dem letzten Update gelesen haben. Bei der Darstellung wird dann geprueft ob der User den Thread schon gelesen hat oder nicht [Hier muss man sich einen cleveren Algorithmus ausdenken] - beim Aufrufen des Threads wird er dementsprechend in diese Liste mit eingetragen.

Wenn dann in einem Thread ein neuer Post ist, wird die Liste einfach geloescht. Threads die aelter als eine bestimmte Grenze sind [z.B. 48 Stunden] werden automatisch als gelesen angezeigt.

Der Speicherverbrauch duerfte dabei zu vernachlaessigen sein, so sind die meisten Threads hier im PHP-Forum schon bei < 100 hits [und da sind afaik auch nicht registrierte User mit drin]. Zudem sollte diese Liste mehrmals zwischendurch aufgrund eines neuen Posts resettet werden. Macht 100 x 4 byte = 400 Byte < 1 kb - und das waere auch bei 500 Threads nicht sonderlich viel, zumal der Speicher der aelteren Threads dafuer wieder freigegeben wird.

Das klingt schon mal Gut.

Wenn ich es richtig verstanden habe habe ich dann folgende Tabelle:

id(integer auto)|threadid(integer)|userid(integer)

Jetzt habe ich aber das Problem, das die einzigartige ID ziemlich schnell nach oben schiest. Also Beispiel:

:arrow: 30 Hits bis nächsten Post
:arrow: 20 Posts = 2030 = 600
:arrow: 100 Threads = 600
100 = 60.000

Jetzt liegt die AutoID bereits bei 60.000. Kann ich dies irgendwie verhindern?

Ich dachte eher daran, zu jedem Thread ein weiteres Feld hinzuzufuegen, in dem dann die ID der User gespeichert werden. Kann man soetwas wie einen array in MySQL verwenden?

Als Alternative wuerde mir einfallen eine feste Groesse fuer die ID zu nehmen [z.B. 4 Byte], diese aneinanderzuhaengen und dann base64-Kodiert [Sofern das noetig ist] in ein Feld des Typs „Text“ zu schreiben.

Wobei ich allerdings auch deine Rechnung nicht verstehe. Bei 100 Usern und 500 Threads waere das absolute Maximum bei 50.000.

Aber es msus noch eine bessere Loesung geben, das kann ja wohl kaum bei anderen Boards so verwendet werden, die haben ja teilweise viel groessere User- und Postmengen. Schau dir vielleicht mal den Code von phpBB an [am besten eine aeltere Version, da sollte weniger Code zu durchforsten sein], vielleicht kommst du darueber drauf.

Ah, jetzt verstehe ich. Werde ich gleich mal ausprobieren.

Habe dazu die Funktion serialize gefunden. Wenn ich das richtig verstehe, kann ich ein Array damit als Blob in die Datenbank speichern.

Danke schon mal

Das mit serialize() und den BLOBs ist nicht bis zum Ende durchdacht. Irgendwie müssen die Informationen schließlich auch abgefragt werden können. Außerdem würde das Feld in der DB einigen Speicherplatz brauchen.

Ich würde eine zusätzliche Tabelle „threads_read“ oder so erstellen, die für einen Nutzer speichert, wann er einen Thread zuletzt gelesen hat:

user_id, thread_id, timestamp

Edit 2: Noch eben zur Verdeutlichung: Jeder Thread, der für den Nutzer mit user_id keinen Eintrag in dieser Tabelle aufweist, ist ungelesen. Jeder Thread, der für den Nutzer einen Eintrag in der Tabelle aufweist, für den der Zeitpunkt des letzten Posts aber jünger ist als das Feld „timestamp“, hat ungelesene Beiträge.

Edit: Nebenbei: Eine Funktion „alle Threads in diesem Unterforum als gelesen markieren“ dann bitte nicht dadurch realisieren, alle Thread-IDs in diese Tabelle einzutragen. Da ist eine Extratabelle sinnvoller. Grob:

subforums_read: subforum_id, user_id, timestamp

Achso, ich brauche ja gar keine einzigartige ID, war gerade darauf total fixiert.

Ich werde es jetzt so wie mermshaus es vorgeschlagen hat machen. Wenn ein Timestamp älter als 7 Tage ist, wird dieser gelöscht. Alles älter als 7 Tage wird dann sowiso als gelesen angezeigt.

Vielen Dank

edit
Die Funktion alles als gelesen makieren, will ich nicht anbieten (Denkemal, dient auch keinem Zweck, außer einer weiteren Datenbankabfrage)