Django 的 MutiTable 对比。抽象继承

Django's MutiTable Vs. Abstract Inheritance

虽然人们普遍认为从长远来看,多 table 继承不是一个好主意 (Jacobian, Others),但我想知道在某些用例中 "extra joins" 在查询期间由 django 创建可能是值得的。

我的问题是数据库中只有一个真实来源。比如说,对于使用身份编号和身份类型标识的人员对象。例如。身份证号码 222,护照类型。

class Person(models.Model):
    identity_number = models.CharField(max_length=20)
    identity_type = models.IntegerField()

class Student(Person):
    student_number = models.CharField(max_length=20)

class Employee(Person):
    employee_number = models.CharField(max_length=20)

在抽象继承中,人的任何子类模型,例如从 Person Abstract Class 继承的 Student、Parent、Supervisor、Employee 等将 identity_number & identity_type 存储在各自的 tables

在多table 继承中,因为它们都共享相同的 table,我可以确定,如果我在 Person 模型中的两列上创建唯一约束,则不会 重复项 将存在于数据库中。

在抽象继承中,为了避免数据库中的重复项,必须在应用程序中构建额外的验证逻辑,因此也会稍微降低性能,这意味着它取消了 django 必须处理的 "extra join"具体继承?

从面向对象的角度考虑数据建模是完全错误的。这是一种不太适合关系数据库的抽象,它隐藏了一些非常重要的细节,这些细节可能会极大地影响性能(如文章中所指出的)或正确性(如你在上面所指出的)。

您的示例的传统 SQL 方法将提供两种可能性:

  1. 有一个 Person table 和 ID,然后 Student,等等。用外键返回它。
  2. 所有内容都有一个 table,还有一些附加字段来区分不同类型的人。

现在,如果您的评估使您更喜欢 1,您可能会注意到在 Django 中这可以通过使用具体的继承模型来实现(它与您上面描述的相同)。在这种情况下,如果您发现 Django 中生成的访问模式更优雅,请务必使用继承。

所以我不是说你不应该使用 继承,我是说你应该只在从 SQL 视角。如果您在上面的示例中这样做,您甚至不会考虑按照抽象继承模型的建议将所有内容拆分为单独的 tables——这具有您注意到的所有问题。