我读过here,多表继承会导致性能问题,建议使用显式的OneToOneField。

这是我的情况:

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')])


我不明白,当多表继承为implemented in exactly the same way时,显式的OneToOneField为什么会带来性能提升:

place_ptr = models.OneToOneField(
    Place, on_delete=models.CASCADE,
    parent_link=True,
)


如果一切正确,如果这是真的,我想知道如何更改我的模型,以便他们使用显式的OneToOneField。因此,如果我创建Book实例,则Product.objects.all()也应检索该Book实例。

最佳答案

我会对多表继承由于多种原因而导致性能问题的结论表示怀疑:


该问题已有5年历史,因此答案可能已过时。
this答案与结论相矛盾
对于为什么模型继承不好的原因,唯一的解释是它需要LEFT JOINs或


  使用多表继承的效率低下的原因是,它为基础模型生成了一个额外的表,并因此产生了用于访问这些字段的额外的JOIN。



上面的说法可能是正确的,但并未说明显式的OneToOneField更好,这是user193130的answer的主要前提。

您应该问自己的真正问题是,我应该将表x和表y连接起来吗?事实证明,这是一个极其复杂的问题。

以下是与此主题相关的资源列表,其中大多数支持我的怀疑:


dani herrera's answer的评论:


  “问:为什么显式的OneToOneFields更好?答:您可以直接访问相关模型而无需左联接。”这有点误导。我认为您仍然需要加入。区别在于您是显式还是隐式地执行此操作。如果我错了请指正我


丹妮·赫拉拉(dani herrara)答复:


  @eugene,你是对的。有空来改善答案。谢谢!

Chris Pratt's answer的最后几行:


  使用单独的模型(和表)仅对模块化具有意义-例如,您将Project子类化以创建特定类型的项目,该项目需要其他字段,但仍需要通用Project的所有字段。

Chris Pratt's other answer中的评论:


  这取决于实际情况。如果存在一个明确的is-关系,那就继续。像Dog(Animal)类一样,则应使用MTI(如果需要的话。采用其他某种形式的继承可能更合适)。但是,在诸如auth.User之类的情况下,UserProfile并不是真正的用户类型,因此OneToOneField更有意义。但是,这里的大警告是使用了UserProfile,因为无法更改User。否则,仅向User添加其他字段会更合适

关于python - 模型继承:显式OneToOneField与隐式多表继承OneToOneField的好处,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58209460/

10-11 19:11