Entwickler-Ecke

Programmiersprachen (Server) - Forum - Thema als gelesen/ungelesen markieren?


Wolle92 - Di 08.04.08 21:00
Titel: Forum - Thema als gelesen/ungelesen markieren?
Hallo,

hab mal ne Frage, wie kann ich es am besten realisieren, dass im Forum für jedes Thema und für jeden User markiert wird, ob ein Thema gelesen wurde oder nicht...

Das ganze in ne SQL-Tabelle speichern ist doof, die müsste ja riesig sein...
User * Themen = Anzahl Felder... Kann ne Menge sein...

Die Zeit des letzten Seitenaufrufs des kompletten Forums mit der Zeit des letzten Beitrags vergleichen ist auch doof, da dann ja nur einmal angezeigt wird, dass nen neuer Beitrag da ist, nochmal Seite aktualisieren und weg isses...

Wie wird das in anderen Foren realisiert?


Yogu - Di 08.04.08 21:14

Schau doch mal im phpBB [http://phpbb.com] nach. Das hat diese Funktion schon intigriert.

Ansonsten kann ich dir nur sagen, was ich denke: Du hast doch für die User eine Tabelle. Da drin sind ja verschiedene Spalten, und jeder User hat einen Wert für jede dieser Spalten. Erstelle doch eine neue Spalte, und schreibe da die Topic-IDs mit Komma getrennt rein. Ich weiß allerdings nicht, wie lange das dauert zu parsen.

Aber hier hat's doch ein paar, die sich damit auskennen sollten. ;)


Christian S. - Di 08.04.08 21:18

Hallo!

Wir machen es fast so, wie Du es beschrieben hast: Für jeden User speichern, wann er was gelesen hat (und auch nur dann, wenn er es gelesen hat). Aber nur für die letzten 14 Tage. Dann wird noch folgendem System entschieden, wann ein Thread ungelesen ist:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
1. Gibt es einen Lesezeitpunkt in der Datenbank und liegt dieser vor der Zeit des letzten Postings -> ungelesen

wenn nicht:
2. definiere einen Grenzzeitpunkt:
   2.1 Der Zeitpunkt 14 Tage vor der aktuellen Uhrzeit
   2.2 liegt der letzte Login vor dem Zeitpunkt aus 2.1, benutze den Zeitpunkt des letzten Logins

3. liegt die Zeit des letzten Postings nach dem Grenzzeitpunkt und nach dem Registierungszeitpunkt des Nutzers -> ungelesen

Ansonsten -> gelesen


Unsere Tabelle bei diesem Vorgehen enthält also immer nur die Lesezeitpunkte der letzten 14 Tage und ist aktuell ca. 18000 Zeilen und 660 KB groß. Also Mini-Peanuts. ;)

Grüße
Christian


Heiko - Mo 14.04.08 19:11

user profile iconYogu hat folgendes geschrieben:
Schau doch mal im phpBB [http://phpbb.com] nach. Das hat diese Funktion schon intigriert.

phpBB2 markiert alle Beiträge als ungelesen, die seit dem vorletzten Login (nicht Seitenaufruf!) geschrieben wurden. Die Daten der aktuellen Sitzung werden dann in Cookis gespeichert. Also eine unschöne Variante.

Was du probieren könntest: leg im Userprofil ein weiteres Feld an in dem du die gelesenen Arrays als serialisiertes Array speicherst. Das spart Reihen, auch wenn dies natürlich Nachteile birgt. Allerdings dürfte der Aufwand geringer sein und die Abfrage auf die Benutzerreihe must du eh machen. Der Performanceverlust würde sich also hauptsächlich auf die größere Datenmenge PHP<->MySQL belaufen. Vorteil: Eine Abfrage reicht, da danach PHP alle Daten hat (zum Nachteil des höheren Speicherverbrauchs pro Seitenaufruf, da ja das array bei einigen Benutzern riesig wird)


Wolle92 - Mo 14.04.08 19:44

das heißt aber soviel wie, dass ich bei einem neuen Beitrag alle User durchgehen muss und in jedem array ungelesen für das thema setzen muss...

Ist vor allem deshalb unschön, da der SQL-Server nicht auf dem gleichen Server wie der Webserver liegt...


Das System von Christian gefällt mir...
Wie sieht das "nur wenn er es gelesen hat" in der Datenbank aus?


Christian S. - Mo 14.04.08 19:56

user profile iconWolle92 hat folgendes geschrieben:
Wie sieht das "nur wenn er es gelesen hat" in der Datenbank aus?
Wenn ein Benutzer ein Thema anklickt, dann wird ein Datensatz angelegt, dass (und wann) der Benutzer das Thema gelesen hat. Guckt ein Benutzer ein Thema nie an, wird für dieses Thema für diesen Nutzer auch kein Datensatz angelegt.

Wir speichern das allerdings nicht in der User-Tabelle, sondern in einer separaten Tabelle, die auch die Lesezeitpunkte für Foren, Blog-Einträge, Blog-Kommentare, Newsfeed-Einträge enthält. Halt alles, was man so lesen kann ;-) Die Speicherung in einer separaten Tabelle macht es auch einfach, Lesezeitpunkte, die weiter als 14 Tage zurückliegen, zu löschen.


Heiko - Mo 14.04.08 19:57

user profile iconWolle92 hat folgendes geschrieben:
das heißt aber soviel wie, dass ich bei einem neuen Beitrag alle User durchgehen muss und in jedem array ungelesen für das thema setzen muss...

Nein. Setzte nicht einfach die Timestamps.

So z.B.

Quelltext
1:
2:
3:
4:
5:
6:
$data = unserialize(%SQL-Feld%);
$read = $data[%TopicID%]>=%lastPostInTopic%;
...
//letztes mal gelesen ggf. aktualisieren
$data[%TopicID%] = now();
..per serialize wieder zurückschreiben


Wolle92 - Mo 14.04.08 20:19

user profile iconChristian S. hat folgendes geschrieben:
user profile iconWolle92 hat folgendes geschrieben:
Wie sieht das "nur wenn er es gelesen hat" in der Datenbank aus?
Wenn ein Benutzer ein Thema anklickt, dann wird ein Datensatz angelegt, dass (und wann) der Benutzer das Thema gelesen hat. Guckt ein Benutzer ein Thema nie an, wird für dieses Thema für diesen Nutzer auch kein Datensatz angelegt.

Wir speichern das allerdings nicht in der User-Tabelle, sondern in einer separaten Tabelle, die auch die Lesezeitpunkte für Foren, Blog-Einträge, Blog-Kommentare, Newsfeed-Einträge enthält. Halt alles, was man so lesen kann ;-) Die Speicherung in einer separaten Tabelle macht es auch einfach, Lesezeitpunkte, die weiter als 14 Tage zurückliegen, zu löschen.


Okay, hab ich das richtig verstanden, dass es eine tabelle gibt, in der dann in einem datensatz username und thread o.ä. gespeichert wird (und datum)? also dass es mehrere Datensätze für die benutzer gibt?


Christian S. - Mo 14.04.08 20:23

Ja, richtig. Unsere Tabelle hat folgende Spalten:

user_id, item_id, item_type, last_read

item_id ist dann die ID des Topic, Forums, Blog-Eintrags, etc. und item_type gibt an, um was es sich handelt.