Django查询性能:使用ForeignKey的单向包含与使用ForeignKey的双向包含&;相关名称

Django查询性能:使用ForeignKey的单向包含与使用ForeignKey的双向包含&;相关名称,django,django-models,foreign-key-relationship,django-queryset,Django,Django Models,Foreign Key Relationship,Django Queryset,全部, 在适当的设计和清洁度以及查询性能方面,您更喜欢哪一种 选项A:(双向参考) 选项B:(单向参考) 从我的观点来看,选择B有一些问题。一是没有什么可以阻止两个或两个以上的城市被标记为某个州或国家的首都。您需要在表单上添加额外的验证,以确保不会发生这种情况 从质疑的角度来看,我认为A仍然更可取。例如,如果您想获得该州首府为X市的所有城市,在第一个城市中,您可以: cities = City.objects.filter(state__capital__name="City X") 在第二种

全部,

在适当的设计和清洁度以及查询性能方面,您更喜欢哪一种

选项A:(双向参考)

选项B:(单向参考)


从我的观点来看,选择B有一些问题。一是没有什么可以阻止两个或两个以上的城市被标记为某个州或国家的首都。您需要在表单上添加额外的验证,以确保不会发生这种情况

从质疑的角度来看,我认为A仍然更可取。例如,如果您想获得该州首府为X市的所有城市,在第一个城市中,您可以:

cities = City.objects.filter(state__capital__name="City X")
在第二种情况下,你必须这样做:

cities = City.objects.filter(state=City.objects.get(name="City X"))
它解析为一个子查询,这可能会降低效率

然而,在选项A中,我认为从一个城市到另一个国家不一定需要FK。在您的模型(*)中,所有城市都位于州内,因此您始终可以通过州获取国家/地区-再次使用额外的FK意味着您需要进行更多验证,以确保您无法将城市分配给与其所在州的国家/地区不同的国家/地区


(*尽管请注意,这实际上并不符合现实:并非所有国家都有州,甚至那些有州的国家通常也会有不属于所有州的城市,如澳大利亚的堪培拉)

选项A更好,因为它包含相同的信息,而不需要一组几乎总是空白的字段(州首府和国家首府)

正如您所注意到的,并不是每个国家都有州/省,因此城市模型中应该同时有国家和州字段。在任何情况下,对于巨大的回报来说,这是一个非常小的冗余量,并且您不太可能遇到规范化问题(例如,给定的州更改其国家的情况极为罕见)。即使每个城市在模型中都有一个关联的状态,最好添加冗余字段以加快查询速度--然后最多处理一个表联接,而不是两个

请注意,华盛顿特区由两个地方组成:华盛顿市和华盛顿州。因此,您的查询:

给我找一个国家,那个国家是美国,首都是华盛顿特区

应读为

Country.objects.filter(code__iexact='US', capital__name__iexact='Washington', capital__state__code__iexact='DC')
(我在这里假设,对于国家和州模型,您实际上添加了一个代码字段来处理缩写)


我要指出的是,其中一些问题似乎是多余的:为什么您需要在国家名称和首都上匹配国家?

我将州和国家都放在城市中()在选项A中,原因与某些城市不属于一个州相同。因此,该州将为空。此外,将使用unique_来确保任何模型中没有重复项,这超出了本问题的范围。因此,您是说您将使用选项A,对吗?Thx Daniel。华盛顿特区是“哥伦比亚特区华盛顿”是美国的首都。是的,我知道。我只是想指出,至少在邮政地址中,华盛顿是城市,华盛顿特区是州。我想把这座城市命名为“华盛顿特区”没有害处。“并将状态值设置为
None
。明白了。是的,将状态保留为空是有意义的,因为它会将状态总数保持在50。”。
cities = City.objects.filter(state=City.objects.get(name="City X"))
Country.objects.filter(code__iexact='US', capital__name__iexact='Washington', capital__state__code__iexact='DC')