在Django中实现粘性线程

时间:2013-06-22 17:34:36

标签: sql django django-models

注意:我是django和数据库的新手,所以请原谅我的无知。

我正在尝试在django中实现一个论坛,并希望拥有粘性线程。我想到的天真的方式是这样定义Thread模型:

class Thread(models.Model):
    title = models.CharField(max_length=max_title_length)
    author = models.ForeignKey(Player, related_name="nonsticky_threads")
    post_date = models.DateField()
    parent = models.ForeignKey(Subsection, related_name="nonsticky_threads")
    closed = models.BooleanField()
    sticky = models.BooleanField()

然后获取粘性线程,执行以下操作:

sticky_threads = Thread.objects.all().filter(sticky=True)

问题是至少在理论上这具有O(n)复杂度,听起来很糟糕。 (由于粘性线程总是显示在第一页上,因此该查询将相当频繁地运行)但是,我不知道数据库/ django聪明性将如何影响最终性能或者它是否仍然不好。

我目前的替代方案是创建不同的Thread和Sticky_Thread类:

class Thread(models.Model):
    title = models.CharField(max_length=max_title_length)
    author = models.ForeignKey(Player, related_name="nonsticky_threads")
    post_date = models.DateField()
    parent = models.ForeignKey(Subsection, related_name="nonsticky_threads")
    closed = models.BooleanField()
class Sticky_Thread(models.Model):
    title = models.CharField(max_length=max_title_length)
    author = models.ForeignKey(Player, related_name="sticky_threads")
    post_date = models.DateField()
    parent = models.ForeignKey(Subsection, related_name="sticky_threads")
    closed = models.BooleanField()

让我在O(1)时间抓住粘性线程,无论如何。我不喜欢这种方法的是,现在如果我想获得所有玩家的线程,我必须实现这样的特殊线程属性:

class Player(models.Model):
    [snip]

    @property
    def threads(self):
        return self.sticky_threads | self.nonsticky_threads

这种方法很难看。

有没有一种明显最好的方式来补充这样的东西?我只是需要做时间,看看天真的方式是否可以接受? (我正在实施这个作为一个学习练习,所以我没有真正的限制,使这个检查有点困难)(如果是这样,你会怎么建议我这样做?(这类似于时间的麻烦吗?)还有更好的选择吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

您对这两项行动的复杂性的分析是远离的。将过滤操作分类为O(n)并将两个单独的类分类为O(1)是不正确的 - 我不知道您使用什么来进行区分。数据库经过高度优化,可根据各个条件进行选择:sticky列上的索引将使筛选查询与从单独的表中查询所有内容几乎完全相同。

第一种方法是毫无疑问正确的方法,只要您确保将sticky列编入索引。