2012-07-15 69 views
1

我对如何构建模型有疑问。为可扩展性/性能选择最佳的Django架构

我想给一些实体投票的可能性,在这种情况下,一篇论文。我想出了这个两种可能性:

选项1:

Link the entity as a relationship 

class Vote(model.Model): 
    author = models.ForeignKey(User) 

    created = models.DateField(auto_now=True) 
    value = models.IntegerField(default=1) 


class Paper(models.Model): 
    author = models.ForeignKey(User) 
    edition = models.ForeignKey(ConferenceEdition) 

    votes = models.OneToMany(Vote) 

优点:

  • 它很容易与模型(ORM)工作
  • 我可以用这个票实体其他
  • 我在呈现HTML时可能需要这些信息,以显示用户已投票的哪些论文。

Desavantages:

  • 恐怕最大的数据库,慢就可以得到的。

选项2:

不链接类

class Vote(model.Model): 
    author = models.ForeignKey(User) 

    created = models.DateField(auto_now=True) 
    value = models.IntegerField(default=1) 

    entity_id = models.IntegerField() 
    entity_type = models.CharField(max_length=255,default='Paper') 


class Paper(models.Model): 
    author = models.ForeignKey(User) 
    edition = models.ForeignKey(ConferenceEdition) 

    num_votes = models.IntegerField(default=0) 

Avantages:

  • 这是一种懒加载的,我有一个计数器,如果我需要的信息我可以去找它。
  • 它的速度更快(我认为)

Desavantages:

  • 必须依靠新的逻辑来更新所有新票。

方案3:

我听

谢谢!

回答

4

只有明确地调用它们时,Django才会加载多个字段。

因此,在你第一种情况:

paper.votes.all() 

如果要加载都在做查询时的票,你可以在Django 1.4做prefetch_related

paper = Paper.objects.get(pk=1).prefetch_related('votes') 

顺便说一句,而不是.all()你可以使用.count(),它会生成一个不同的数据库查询,因为它只需要计数值,而不是将它们检索到django/python。

还有第三种方法:

您coud在模型中的额外字段:votes_count,你会在pre_save更新(),它会认为价值给你。这样你就可以得到两个:你可以查询所有的选票,但你也可以只抓一个数字。

+1

+1你绝对应该考虑第一种和第三种方法的结合。我不确定的一件事是拥有“票”ManyToManyField,因为我不确定相同的投票是否适用于多篇论文。如果这不是OneToMany就足够了。 – astevanovic 2012-07-16 00:05:18

+0

对不起,我的意思是oneToMany。我的错,我会编辑这个问题。 – 2012-07-16 08:20:50