0

在我正在开发的 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 对象。我知道创建/评级会经常进行。

什么更

4

1 回答 1

3

取决于问题的规模。如果您预计会有大量写入流量,这可能是个问题。扩展写入比读取(复制、缓存等)要困难得多。也就是说,如果没有这个额外的查询会给您带来任何问题,您可能会走很长一段路。

根据您的统计信息必须是最新的,您可以让其他一些流程(非网络会话)通过并每晚更新这些统计信息。

于 2009-01-16T01:46:24.550 回答