2012-02-26 65 views
1

这可能是一个关于数据库的通用问题,而不是django,但我们走吧。关系(x> 1)到多个

我经常有什么可以被认为是2对多关系。 例如,我在我的项目中有一个类匹配,这是两个团队之间的相遇。

起初,我是用许多一对多:

Match(Model): 
    teams = ManyToManyField('Team', related_name='matches') #Always two teams 

它结束了对比赛相关的页面非常低效的。尤其是在django 1.3中,因为没有与many_to_many关系的select_related等效。当你现在只有两个元素时,必须迭代有点痛苦。

然后我切换到这种模式:

Match(Model): 
    teams = ManyToManyField('Team', related_name='matches') #Always two teams 
    team1 = ForeignKey('Team') 
    team2 = ForeignKey('Team') 

当我想显示匹配相关的网页,我可以使用select_related和非常有效地显示两队。 当我在球队页面上时,我可以按照“比赛”关系来获取所有比赛。 但我发现处理一个关系的3个领域是非常可怕的。

我在做对吧?你会推荐什么 ?

+0

您可以详细说明您的缓存组织吗? – jpic 2012-02-26 13:43:33

+0

标题中的两个标签,两个标签都有不同的分隔符...... ARGH! – 2012-02-26 15:32:21

+0

@jpic我不明白 – Ashe 2012-02-26 23:18:10

回答

1

我在那里看到很少的解决方案。

如果你不预测,在未来的比赛会之间的团队超过两个可能是最适合你的,只是从你的第二个设计删除多对多场的其他号码上播放:

Match(Model): 
    team1 = ForeignKey('Team') 
    team2 = ForeignKey('Team') 

它会在数据库中删除redundation,使Match修改更容易(你不必team领域和相应的team1team2领域之间的担心凝聚力)。同时也不可能与其他数量的相应的团队创建一个匹配,而导致数据库一致性。

另一方面,你失去了灵活性,编写查询更困难,因为有两个字段需要检查而不是一个。

2.

您可能需要使用一个缓存。事实上 - 你所拥有的这两个领域除此之外别无其他,但将其移至专用缓存数据库可以使其更有效,并将主数据库与缓存值分开,从而实现更清晰的数据库设计。

写自己的多对多提取器。这并不难,但相当丑陋。你必须选择您感兴趣的球队中,然后以某种方式连接它们匹配的对象,例如:

matches # Match QuerySet 
related_teams = Team.objects.filter(match__in=matches) 
matches_map = {} 
for t in related_teams: 
    matches_map[t.match_id]= matches_map.get(t.match_id, []).append(t) 

for m in matches: 
    m.fetched_teams = matches_map[m.pk] 

3.5。

Django的新版本将有一个prefetch_related()方法,这意味着与ManyToMany查询,但我想你没有那么多的时间。

+0

1.我们用两支球队的临时球队进行两场比赛(这在我们的情况中非常罕见),所以比赛中总是有两支球队。 “裁员”根本不是问题,价值从不改变,所以在创作过程中确保团队,团队1和团队2是正确的并不难。 – Ashe 2012-02-26 23:27:10

+0

2.我不明白,你正在处理缓存中的所有多对多关系?像redis?这听起来像是很多一致性问题。我很想看到关于这个的教程。 – Ashe 2012-02-28 08:39:07

+0

3.我已经做了很多关系,我推荐使用,虽然允许选择中间关系(即使它没有明确确定)+ select_related。但是当总是存在2个关系时,我发现迭代非常难看。 – Ashe 2012-02-28 08:41:45