4

虽然普遍认为多表继承从长远来看不是一个好主意(雅可比其他),但我想知道在某些用例中,django 在查询期间创建的“额外连接”是否值得。

我的问题是数据库中有一个单一的真相来源。比如说,对于使用身份号码和身份类型识别的人员对象。例如 ID 号 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 抽象类继承的任何子类模型(例如 Student、Parent、Supervisor、Employee 等identity_number)都将identity_type存储在各自的表中

在多表继承中,由于它们都共享同一个表,我可以确定如果我在 Person 模型中的两个列上创建唯一约束,那么数据库中将不存在重复项

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

4

1 回答 1

3

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

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

  1. 有一个Person带有 ID 的表,然后Student等带有外键。
  2. 对所有内容都有一个表格,并带有一些额外的字段来区分不同类型的人。

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

所以我并不是说你不应该使用继承,我是说你应该只在你从 SQL 的角度对数据建模之后再看它。如果您在上面的示例中这样做,您甚至不会考虑将所有内容拆分到单独的表中——这有你注意到的所有问题——正如抽象继承模型所建议的那样。

于 2016-11-25T09:57:16.840 回答