拥有更新字段或COUNT查询是“更好”吗?

时间:2009-01-16 01:40:47

标签: django database-design django-models django-signals django-aggregation

在我正在研究的Django应用程序中我已经开始了:

class Parent(models.Model):
    name = models.CharField(...)

    def num_children(self):
        return Children.objects.filter(parent=self).count()

    def avg_child_rating(self):
        return Child.objects.filter(parent=self).aggregate(Avg('rating'))

class Child(models.Model):
    name = models.CharField(...)
    parent = models.ForeignKey(Parent)
    rating = models.IntegerField(default=0)

我打算经常访问 avg_child_rating 。如果我执行以下操作,它会优化

class Parent(models.Model):
    ...
    num_children = models.IntegerField(default=0)
    avg_child_rating = models.FloatField(default=0.0)

def update_parent_child_stats(sender, instance, **kwargs):
    num_children = Child.objects.filter(parent=instance.parent)
    if instance.parent.num_children != num_children:
        instance.parent.num_children = num_children
        instance.parent.avg_child_rating = Child.objects.filter(instance.parent=self).aggregate(Avg('rating'))

post_save.connect(update_parent_child_stats, sender=Child)
post_delete.connect(update_parent_child_stats, sender=Child)

现在的不同之处在于,每次创建/评级/删除子项时,都会更新Parent对象。我知道创建/评级会经常完成。

还有什么昂贵的

1 个答案:

答案 0 :(得分:3)

取决于问题的严重程度。 如果您预计会有大量写入流量,这可能是一个问题。缩放写入比读取(复制,缓存等)要困难得多。也就是说,如果没有这些额外的查询可能会导致任何问题,您可能会走很长的路。

根据您的统计信息的最新状态,您可以通过其他进程(非网络会话)来完成并每晚更新这些统计信息。