Seite 1 von 1

Threads als "ungelesen" markieren

Verfasst: Mi Sep 12, 2012 3:21 pm
von Xin
Ich würde gerne mal über folgendes Problem hier diskutieren.

Da wir ja an einem eigenen CMS arbeiten, stellt sich mir eine performancekritische Frage: Wer sich hier anmeldet, bekommt die Information, welche Threads und Boards Postings enthalten, die noch nicht gelesen sind. Also muss es irgendwo eine Datenbank geben, welche Threads von mir gelesen wurden und welche nicht.

Nehmen wir an, wir hätten 50'000 User, 500'000 Threads und 5'000'000 Postings. Nun melde ich mich an: habe ich jetzt 500'000 ungelesene Threads, also 500'000 Einträge in meiner Datenbank? Oder ist die DB leer, weil ich noch nichts gelesen habe?
Was passiert, wenn ein Posting erstellt wird? Bekommt jeder User (50'000 User...) einen Eintrag, dass er hier noch lesen soll?

Wie würdet ihr das performant lösen?

Re: Threads als "ungelesen" markieren

Verfasst: Mi Sep 12, 2012 4:16 pm
von Kerli
Die Information welche Threads noch nicht gelesen worden sind müssen wohl für jeden Nutzer individuell gespeichert werden. An deren Menge kann man wohl nichts ändern. Nachdem man im Allgemeinen davon ausgehen kann das Beiträge entweder gelesen oder als gelesen markiert werden dürfte es weniger Speicher brauchen zu speichern was noch nicht gelesen wurde als umgekehrt.

Optimierungen fallen mir ein paar ein:

Man könnte den ungelesen Status vererben, heißt also es gibt global ungelesen (nur für neu registrierte Benutzer die noch nie etwas gelesen haben nützlich) und dann für jede Ebene in der Hierarchie. Das hilft Platz zu sparen für Benutzer die nichts oder nur aus ein paar Foren etwas lesen.

Um nicht bei jeden neuen Posting jede Menge Einträge in der Datenbank zu generieren könnte man zb. auch einzelne Postings oder Threads ab einem gewissen Posting als von niemanden (außer dem Ersteller) gelesen markieren. So lange es nur wenige gelesen haben könnte man eine Liste der Benutzer die es gelesen haben führen und erst ab einer gewissen Anzahl wechseln auf ungelesen.

Weiters könnte man auch das Änderungsdatum mit einbeziehen und alle Beiträge seit der letzten Aktion des Nutzers bei einer erneuten Aktion als ungelesen markieren.

Re: Threads als "ungelesen" markieren

Verfasst: Mi Sep 12, 2012 7:41 pm
von nufan
Ich hab mir grade nochmal die phpBB-Datenbank angesehen. Es gibt eine Tabelle phpbb_topics_track mit user_id, topic_id, forum_id und mark_time, was ganz logisch erscheint. Mich verwirrt nur etwas, dass diese Tabelle in meinem Test-Forum leer ist?! Vielleicht werden da nur alte Zustände archiviert, aktuelle Themen im Hauptspeicher gehalten.

Re: Threads als "ungelesen" markieren

Verfasst: Mi Sep 12, 2012 7:53 pm
von fat-lobyte
Ich würde die Idee mit dem Datum etwas weiterführen:

Für jeden Benutzer wird ein Datum gespeichert (time_all_read), ab dem alles als ungelesen angezeigt wird. Liest der User bestimmte Beiträge, werden diese der Datenbank hinzugefügt.

Hat er alle Beiträge einer Zeitperiode gelesen, die an das letztgespeicherte Datum anschließt, wird das Datum auf das Ende der Zeitperiode gesetzt und alle einträge der Periode entfernt. Außerdem kann der User mit "alle Beiträge als gelesen markieren" das Datum manuell aktualisieren und alle "gelesen"-Einträge löschen.

Also so ungefähr habe ich mir das vorgestellt:

Code: Alles auswählen

struct Post {
    unsigned int time;
    
    bool operator < (const Post& other) { return time < other.time; }

};

struct DataBase {
    std::set<Post> all_posts;
};

struct User {
    void readPost(const Post& p)
    {
        if (p.time < last_time) return;
        
        std::pair<XYZ, XYZ> mm = mismatch(read_posts.begin(), read_posts.end(), database->begin(), database->end())
        
        read_posts.delete(read_posts.begin(), mm.first());
        last_time = read_posts.begin()->time;
    }
    
    std::vector<Post> getUnreadPosts()
    {        
        Post first_read = read_posts.front();
        
        auto since_post = std::find(database->begin(), database->end(),first_read);        
                
        std::vector<Post> unread_posts(database.end() - since);
        auto it = unread_posts.begin();        
        it = std::set_difference(since, database.end(), read_posts.begin(), read_posts.end());
        
        unread_posts.resize(it - unread_posts.begin());        
        return std::move(unread_posts);
    }
    
private:
    DataBase* database;
    unsigned int last_time;
    std::set<Post> read_posts;
};

Re: Threads als "ungelesen" markieren

Verfasst: Do Sep 13, 2012 4:55 pm
von canlot
Wenn ein User sich registriert hat hat er kein ungelesene Postings. Wenn ein User ein Posting nicht gelesen hat dann wird er in die Datenbank geschrieben. Wenn er dann gelesen hat wird es aus der Datenbank wieder gelöscht.

Re: Threads als "ungelesen" markieren

Verfasst: Do Sep 13, 2012 4:59 pm
von XinQuadrat
Tatsache... habe mich gerade neu angemeldet und keine ungelesenen Beiträge... hätte ich anders erwartet, ist aber mal ein Implementierungsindiz.

Ich gehe mich dann mal wieder löschen... ^^

Re: Threads als "ungelesen" markieren

Verfasst: Do Sep 13, 2012 5:23 pm
von Kerli
XinQuadrat hat geschrieben:Tatsache... habe mich gerade neu angemeldet und keine ungelesenen Beiträge... hätte ich anders erwartet, ist aber mal ein Implementierungsindiz.
Wenn du es gleich machen möchtest kannst dir auch einfach den Quellcode anschauen. Ist vielleicht etwas einfacher als das Verhalten zu studieren ;)

Re: Threads als "ungelesen" markieren

Verfasst: Do Sep 13, 2012 5:25 pm
von Xin
Kerli hat geschrieben:
XinQuadrat hat geschrieben:Tatsache... habe mich gerade neu angemeldet und keine ungelesenen Beiträge... hätte ich anders erwartet, ist aber mal ein Implementierungsindiz.
Wenn du es gleich machen möchtest kannst dir auch einfach den Quellcode anschauen. Ist vielleicht etwas einfacher als das Verhalten zu studieren ;)
Erstens denke ich gerne selbst, zweitens kann ich mir den Quellcode notfalls immernoch anschauen, drittens kostet es vermutlich mehr Zeit, den Quellcode von phpBB zu verstehen, als ihn neu zu schreiben.