1

Group と Person の 2 つのモデルを持つ Django プロジェクトがあります。グループには、Person オブジェクトまたは他の Group オブジェクトを含めることができます。グループは循環を形成できません (つまり、グループ A を含むグループ B を含み、グループ A を含みます)。その結果、Person オブジェクトがリーフであるツリー構造になります。

私の質問は、できるだけ少ない SQL クエリで、高レベルのグループ (ルート グループなど) 内に含まれるすべての Group オブジェクトと Person オブジェクトをカウントするにはどうすればよいですか?

O(N) (N はサブグループの数) を使用した単純なアプローチ SQL クエリは次のようになります。

def Group(models.Model):
    name = models.CharField(max_length=150)
    parent_group = models.ForeignKey('self', related_name=child_groups, null=True, blank=True)

    # returns tuple (# of subgroups, # of person objects)
    def count_objects(self):
        count = (self.child_groups.count(), self.people.count())
        for child_group in self.child_groups.all():
            # this adds tuples together ( e.g: (1,2) and (1,2) make (2,4) )
            tuple(map(operator.add, count, child_group.count_objects()))

def Person(models.Model):
    user = models.ForeignKey(User)
    picture = models.ImageSpecField(...)
    group = models.ForeignKey('Group', related_name="people")

これを改善する方法はありますか、またはこれらの値を Group オブジェクト内に保存する必要がありますか?

4

2 に答える 2

1

したがって、これは他の多くの人が取り組んできた既存の問題です。Django を使用している場合は、こちらを確認してください: http://django-mptt.github.com/django-mptt/index.html

于 2012-08-29T03:32:55.800 に答える
0
  • Django ではこれを直接サポートしていませんが、 Postgres 内では再帰クエリを使用できます。

  • または、カウントの非正規化を検討することもできます。これを行うライブラリがある可能性があります。簡単なグーグルで私にくれた:http://pypi.python.org/pypi/django-composition/

  • 同じ値を頻繁に選択する必要があり、それらがそれほど変化しない場合は、それらをキャッシュしてみてください。

于 2012-08-29T03:38:17.237 に答える