2012-07-15 58 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