Django的多表继承与抽象继承对比

4
虽然大多数人普遍认为长期使用多表继承并不是一个很好的想法(Jacobian, Others),但我想知道在某些用例中,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 Abstract Class继承,将在它们各自的表中存储identity_number和identity_type。
在多表继承中,由于它们共享同一张表,我可以确定如果在Person Model上创建两个列的唯一约束,则数据库中不会存在重复项。
在抽象继承中,为了避免数据库中出现重复项,必须在应用程序中构建额外的验证逻辑,这也会略微降低性能,从而取消Django在具体继承中必须进行的“额外连接”。
1个回答

3
在考虑数据建模时,将其视为面向对象的抽象是一个错误。这种抽象不适用于关系型数据库,并且会隐藏一些非常重要的细节,可能会对性能(正如文章中所指出的)或正确性(正如你上面指出的)产生巨大影响。
传统的 SQL 方法提供了两种可能性:
1. 具有 IDs 的 Person 表,然后通过外键返回到 Student 等表。 2. 为所有内容提供单个表,带有一些附加字段以区分不同类型的人员。
如果您的评估使您更喜欢第一种方法,您可能会注意到,在 Django 中,可以通过使用具体继承模型(与您上面描述的相同)来实现这一点。在这种情况下,请尽管使用继承,如果您发现结果访问模式在 Django 中更加优雅。
因此,我并不是说您不应该使用继承,而是说您应该在从 SQL 视角建模数据之后再考虑它。如果在上面的示例中进行了这样的建模,您甚至不会考虑将所有内容拆分成单独的表——这就像抽象继承模型建议的那样,存在着所有您所指出的问题。

我喜欢指针。面向对象编程是一种抽象,不太适合关系型数据库,因为它让我想到要专注于数据及其关系。对于当前的项目,我将选择选项一。 - lukik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接