我正在创建数据库项目,有一件事对我来说不是那么清楚。看看这个:
现在我不确定制作物理模型的最佳方法是什么。 TOOL和RESOURCE不需要除ITEM之外的任何其他字段。只有Recipe需要新列(for)。但我必须以某种方式将食谱与工具和资源区分开来。好吧,我可以创建2个相同的表,其中包含不同的资源和工具名称,以及一个用于配方的表,但是我对项目做了什么呢?创建是视图吗?然后它不会真正进行子类化。
或者我只是创建这样的东西:用(id,name,description)创建ITEM表,然后只用RESOURTS和(item_id)那个外键和工具相同,并添加触发器,当我插入资源时,它真正添加到ITEM然后只是在资源中添加外键?这似乎是最明智的选择,但它有可能吗?
答案 0 :(得分:3)
这是一个经典的"它取决于"回答。答案实际上取决于潜在的关系以及项目是否属于多种类型。
如果存在所有项目都可以存在的关系,那么单个项目表将更可取,因为您的关系表中可以有一个外键列。如果存在只有特定类型的项目可以拥有的关系,
然后你将需要使用Class Table Inheritance,所以正如你所说的工具,你会这样做
有一个名为Tools
的表,其中一个主键列ItemID
引用了Item。这样,您可以创建限制关系Tools.ItemID
的外键
到某种类型的物品。如果一个项目可以属于多个类型,那么几乎可以肯定使用类表继承。
如果您不需要限制关系,并且某个项目只能属于一种类型,那么您可以通过在Items表格中添加ItemType
列来识别项目类型,无需使用表继承。
如果不存在多个项类型可能存在的关系,并且会出现只有一个可以出现的关系,那么使用3个表可能会更简单,维护更少,并且使用视图要结合它们,它仍然应该提供所需的所有功能。
总之,继承将需要更多的表和更多的管理,但更灵活,因此它取决于。
答案 1 :(得分:2)
根据您提出的要求,我建议仅使用分区属性实际执行一个表(项目),例如: item_type
。您可以使用检查约束来确保仅适用于配方的额外列对于其他项类型为空,对于配方不为null。
如果您的应用程序有意义,例如,如果您必须强制ORM按照您希望的方式工作,那么您可以为这三种不同的子类型创建视图。
如果您的需求扩展为每个子类型包含许多不同的谓词(列),那么您可能需要考虑将不同的谓词拆分为子类型表,将公共谓词保留在超类型级别。在任何一种情况下,您仍然希望拥有分区属性。什么时候实现物理子类型没有硬性规定。这是一个权衡问题,在某种程度上取决于个人偏好。
答案 2 :(得分:1)
设计子类(也称为“IS-A”关系)的问题在这里不时出现。您可以访问class-table-inheritance标记并阅读信息标签,对问题进行一般性讨论。此外,GarethD给出的Fowler参考文献将为您提供一个很好的治疗方法。