理解类表继承

Posted

技术标签:

【中文标题】理解类表继承【英文标题】:understanding class table inheritance 【发布时间】:2012-02-22 23:48:29 【问题描述】:

我有一个名为 products 的产品表 它有 3 个字段(名称、模型(PK)和类名)。类对应一个表。 所以这里是一个例子:

产品表:

model | name | class_Name
z123  | Abcd | AMPS

AMPS 表:

model | attribute_1 | attribute_2
z123  | blah blah   | blah blah

问题:

我是否应该有一个包含 PK(模型)及其对应类名的表,然后在我的产品表中使用类 ID?拥有一个包含所有模型及其类的表会更有效吗?

【问题讨论】:

添加了 SQL 标签,这样您就可以真正得到答案了。 我看不出你所做的有什么问题,而且我怀疑添加表格会有所帮助。但是,您应该考虑提出更具体的问题。你的目标是什么?如果您担心效率,您想优化什么? @Paul Keister。我只是想以“正确的方式”做事。 【参考方案1】:

已经有一个公认的答案,但我添加以下内容是为了让其他遇到此问题的人受益。请注意,此解决方案与在主表中指示子类明显不同。在我看来,它既简单又灵活。

您的案例看起来像是被称为“泛化专业化”(简称 Gen-Spec)的设计模式的一个实例。面向对象的程序员很熟悉 gen-spec 模式。在教授继承和子类时,它会在教程中介绍。

实现 gen-spec 模式的 SQL 表的设计可能有点棘手。数据库设计教程经常掩盖这个主题。但它在实践中一次又一次地出现。

如果您在网络上搜索“泛化专业化关系建模”,您会发现几篇有用的文章教您如何做到这一点。您还会在此论坛中多次提及此主题。

这些文章通常向您展示如何设计一个表来捕获所有通用数据,并为每个子类设计一个专用表,其中包含该子类特定的所有数据。有趣的部分涉及子类表的主键。您不会使用 DBMS 的自动编号功能来填充子类主键。相反,您将对应用程序进行编程,以将从通用表获得的主键值传播到适当的子类表。

这会在通用数据和专用数据之间创建双向关联。每个专用子类的简单视图将一起收集通用数据和专用数据。一旦掌握了它就很容易,而且性能相当不错。

【讨论】:

【参考方案2】:

这看起来像一个“子类”(又名“类别”)层次结构。如果您有并且总是只有AMPS 而没有其他“子类”,那么您可以考虑将其与Product 合并。否则,它看起来不错。

顺便说一句,有3 ways 在关系数据库中实现类层次结构,每个都有优点和缺点。将所有类保存在一个表中就是其中之一,但可能难以维护,并且对于某些类型的引用完整性可能会出现问题。您已经使用的模型(“每个表的类”)可能应该是您的默认选择,除非有令人信服的理由...

【讨论】:

是的,每个产品总会有一个特定的类别。我知道实现类层次结构的 3 种方法,并且“每个表的类”看起来是解决我遇到的特定问题的最合乎逻辑的方法。谢谢

以上是关于理解类表继承的主要内容,如果未能解决你的问题,请参考以下文章

学说(连接)类表继承中根实体的查询字段

如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?

教义2中的类之间的多个CTI(类表继承)?

Symfony/Doctrine 类表继承和外键作为主键

在 Doctrine ORM 2 中加入类表继承时出现“主键 elementId 的缺失值”

C++虚基类表指针字节对齐模型