模型继承:显式OneToOneField与隐式多表继承OneToOneField的好处 [英] Model inheritance: benefits of explicit OneToOneField vs implicit multi-table inheritance OneToOneField
问题描述
我在此处多表继承会导致性能问题,建议使用显式的OneToOneField.
I read here that multi-table inheritance can cause performance issues, and instead explicit OneToOneField is recommended.
这是我的情况:
class Product(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=10)
category = models.ForeignKey('Category', on_delete=models.CASCADE, blank=False)
class Book(Product):
publisher = models.CharField(max_length=50)
author = models.CharField(max_length=50)
isbn = models.CharField(max_length=50)
class Shoes(Product):
size = models.PositiveSmallIntegerField()
colour = models.CharField(max_length=20, choices=[('black', 'Black'), ('white', 'White')])
当多表继承为如果所有情况都是如此,我想知道如何更改我的模型,以便他们使用显式的OneToOneField.因此,如果我创建Book实例,则 Product.objects.all()
也应检索该Book实例.
If this is true despite everything, I would like to know how could I alter my models so they use explicit OneToOneField. So, if I create a Book instance, Product.objects.all()
should retrieve that instance of Book, too.
推荐答案
我对基于多种原因的多表继承会导致性能问题的结论有些怀疑:
I'd be a bit skeptical of the conclusion that multi-table inheritance causes performance issues for a variety reasons:
- 该问题已有5年历史,因此答案可能已过时.
- 此答案与结论相矛盾
- 给出为什么模型继承不好的唯一解释是它需要左联接或
- That question is 5 years old, so the answers might be outdated.
- this answer contradicts that conclusion
- The only explanations given for why model inheritance is bad are that it requires LEFT JOINs or
使用多表继承之所以效率低下,是因为它为基础模型生成了一个额外的表,并因此产生了用于访问这些字段的额外的JOIN.
The reason using multi-table inheritance is inefficient is because it generates an extra table for the base model, and therefore extra JOINs to access those fields.
上面的说法可能是正确的,但没有解释如何显式的 OneToOneField
更好,这是user193130的
The above statement may be true, but it doesn't explain how explicit OneToOneField
s are better, which is the main premise of user193130's answer.
您应该问自己的真正问题是,我应该将表x和表y连接起来吗?,事实证明,这是一个极其复杂的问题.
The real question you should ask yourself is, should I join table x and table y?, which, as turns out, is an extremely complicated question.
以下是与此主题相关的资源列表,其中大多数支持我的怀疑态度:
Here is a list of resources related to this topic, most of which support my skepticism:
问:为什么显式的OneToOneFields更好?答:您可以直接访问相关模型而无需左联接."这有点误导.我认为您仍然需要加入.区别在于您是显式执行还是隐式执行.如果我错了请纠正我
"Q: Why are explicit OneToOneFields better? A: You can access directly to related model without left joins." this is somewhat misleading. I think you need joins anyway. The difference is whether you do it explicitly or implicitly. Please correct me if I'm wrong
丹妮·赫拉拉(dani herrara)回复的
:
to which dani herrara replies:
@eugene,你是对的.有空来改善答案.谢谢!
@eugene, you are right. Be free to improve answer. Thanks!
使用单独的模型(和表)仅出于模块化目的才有意义-这样,您可以将Project子类化,以创建特定类型的项目,该项目需要其他字段,但仍需要通用Project的所有字段.
Using separate models (and tables) only makes sense for the purposes of modularization -- such that you subclass Project to create a specific kind of project that requires additional fields but still needs all the fields of a generic Project.
这取决于情况.如果存在明确的is,则说明存在一种关系.像类Dog(Animal)一样,则应使用MTI(如果需要的话.某些其他形式的继承可能更合适).但是,在诸如auth.User之类的情况下,UserProfile并不是真正的用户类型,因此OneToOneField更有意义.但是,这里的大警告是使用了UserProfile,因为无法更改User.否则,仅向User添加其他字段会更合适
It depends on the situation. If there's a clear is-a relationship going on. Like class Dog(Animal), then you should use MTI (If it's called for. Some other form of inheritance may be more appropriate). But, in the case of something like auth.User, a UserProfile is not really a type of User, so OneToOneField makes more sense. However, the BIG caveat there is that UserProfile is used because User cannot be altered. Otherwise, simply adding additional fields to User would be more appropriate
这篇关于模型继承:显式OneToOneField与隐式多表继承OneToOneField的好处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!