Ein Forum (Forum) habe Themen (Topic) und jedes Thema habe Beiträge (Post). Ein Forum habe außerdem Benutzer (User), die Beiträge schreiben.
Code: Alles auswählen
class User(models.Model):
"""Represents a forum user who writes posts."""
name = models.CharField()
class Forum(models.Model):
"""Represents a list of related conversations."""
title = models.CharField()
class Topic(models.Model):
"""Represents a single conversation consisting of postings."""
title = models.CharField()
forum = models.ForeignKey(Forum, related_name='topics')
class Post(models.Model):
body = models.TextField()
date = models.DateTimeField()
author = models.ForeignKey(User, related_name='all_posts')
topic = models.ForeignKey(Topic, related_name='posts')
So weit, so gut.
Für jeden User möchte ich nun festhalten, welche Beiträge er gesehen hat bzw. welche noch neu für ihn sind. Wie mache ich dies und insbesondere, wie mache ich dies einigermaßen speichereffizient?
Der naive Ansatz wäre wohl, pro User und Thema einen Eintrag in einer speziellen Tabelle abzulegen. Entweder
Code: Alles auswählen
class Read(models.Model):
topic = models.ForeignKey(Topic)
user = models.ForeignKey(User)
Code: Alles auswählen
class Unread(models.Model):
topic = models.ForeignKey(Topic)
user = models.ForeignKey(User)
Speichere ich die ungelesenen Themen, müsste ich bei jeder Änderung hier pro Anwender einen Datensatz schreiben und später diese wieder löschen. Sagen wir einmal, das pro Tag 40 Beiträge geschrieben werden (was ungefähr für dieses Forum hinkommt) und User 1x pro Woche lesen, dann sind es noch 1.400.000 Datensätze. Hm.
Ich möchte allerdings nicht einfach nur ablegen, wann der letzte Login war, um dann alles, was seit diesem Zeitpunkt neu ist, zu markieren. Ich hasse, wenn Foren vergessen, was ich noch nicht gelesen habe (dieses Forum macht es auch manchmal).
Ich könnte die Menge der Datensätze reduzieren, indem ich die Informationen kompakt kodiere. Pro Forum könnte ich die Information, welche Themen bis zu welchen Beiträgen gelesen wurden, in einem String ablegen.
Code: Alles auswählen
12812:4522,12813:4598 # Topic:Post,Topic:Post,...
Wenn ich Beiträge nicht global durchnummeriere, sondern pro Forum, kann ich die Liste verkürzen, indem ich ausnutze, dass in der Regel das Gros der Beiträge bekannt ist und ich ein (offene) Intervale benutze, die Beiträge aufzuzählen:
Code: Alles auswählen
4528,4522-4518,4507- # ID oder ID2-ID1 oder ID-
Es muss doch einen besseren Ansatz geben!
Stefan