2009-09-02 92 views
0

我试图围绕正确的设计来计算多个项目的平均值,在我的案例中是啤酒。网站用户可以查看各种啤酒,并根据这些评论给所有啤酒评级(对该啤酒的所有评论的平均值)。每份啤酒评论都有5项评级标准,并对这些标准进行加权,然后计算为该特定评审的整体评级(由该用户评估)。获得平均值的计算和数据库设计

以下是一些现有的相关模型。我目前的想法是,所有的啤酒评论都会出现在你自己的桌子上,就像你看到的那样。

class Beer(models.Model): 
    name = models.CharField(max_length=200) 
    brewer = models.ForeignKey(Brewery) 
    style = models.ForeignKey(Style) 
    ..... 

class Beerrating(models.Model): 
    thebeer = models.ForeignKey(Beer) 
    theuser = models.ForeignKey(User) 
    beerstyle = models.ForeignKey(Style) 
    criteria1 = models.IntegerField 
    ... 
    criteria5 = models.IntegerField 
    overallrating = models.DecimalField 

我真正的问题是,如何根据啤酒的所有评论来计算总体啤酒平均值?我是否在啤酒模型中保持运行状态(例如,#评论和总积分;每次评论后都会更新)还是仅仅计算平均值?我目前的数据库设计方式是否有问题?

我也会计算一个顶级啤酒列表(100个最高评分的啤酒),所以这是另一个计算,我将与评级做。

任何帮助,非常感谢。这是我的第一个网络应用程序,所以请原谅我的小白眼。我还没有选择数据库,所以如果MYSQL或PostgresSQL在某种程度上优于其他数据库,请提供您的偏好,或者为什么如果您有时间。我会在这两个数据库之间进行选择。我也在使用Django。谢谢。

回答

2

只要您使用的是Django版本1.1,您可以使用新的聚合功能来计算平均值,只要您需要它。

喜欢的东西:

from django.db.models import Avg 
beers_with_ratings = Beer.objects.all().annotate(avg_rating=Avg('beer__overallrating')) 

现在每个啤酒对象将有一个avg_rating属性,该属性是它的每个相关联的评级的overallrating领域的平均水平。

然后让高层100:

beers_with_ratings.order_by('avg_rating')[:100] 

至于数据库的选择,无论是对这种事情完全没有问题。聚合是关系数据库的基本特征,Postgres和Mysql都可以做到这一点,没有任何问题。

+0

感谢您的信息!我知道1.1最近出来了,但我还没有玩过它。看起来我现在有一个很好的理由。 – kfordham281 2009-09-03 13:37:39

0

您可能想看看Django ratings模块。它的结构非常好,并提供强大的评分系统。并不是在同一时间过于复杂(但如果这是你的第一个网络应用程序,它可能看起来有点吓人)。 你不需要直接处理计算平均值等。

编辑:是有点更有帮助

如果你使用Django的收视率,你的models.py可能会是这个样子:

class Beer(models.Model): 
    name = models.CharField(max_length=200) 
    brewer = models.ForeignKey(Brewery) 
    style = models.ForeignKey(Style) 
    ..... 
    criteria1 = RatingField(range=5) # possible rating values, 1-5 
    ... 
    criteria5 = RatingField(range=5) 

无需Beerrating模型。相反,所有的评级信息都将存储在Django评级的投票+评分模型中。

+0

使用此可插拔应用程序与“手动”构建应用程序有什么优势? – kfordham281 2009-09-04 12:34:53