[英]Storing inherited objects in a database
我试图找出将对象模型中的继承关系映射到关系数据库的最佳方法。 例如,考虑以下类结构。
public Class Item
{
public String Name{get; set;}
public int Size {get; set}
}
public Class Widget:Item
{
public String Color{get; set;}
}
public Class Doohicky:Item
{
public String Smell{get; set;}
}
以下是我正在考虑如何将此结构保存到数据库的一些选项。
选项1:所有项目类型的单表
Items Table: ItemID, Name, Color, Smell
这很糟糕,因为它需要NULL值。
选项2:每种项目类型的单独表格
Widgets Table: WidgetID, Name, Color
Doohicky Table: DoohickyID, Name, Smell
这样更好,但列出所有项目会更加困难
选项3:链接表
Items Table: ItemID (PK), Name, Size
Widgets Table: WidgetID (PK), ItemID (FK), Color
Doohicky Table: DoohickyID (PK), ItemID (FK), Smell
我认为这个选项是最好的,因为它阻止我在任何字段中都有Null值,而且它会更容易列出所有Items,和/或创建特定类型的Item(Widgets或Doohickies)列表。
但是,我不确定如何创建Items表与Widgets和Doohickies表之间的关系。 我不想在任何表中引用行引用Items表中的相同ItemID。
例如,当我向Widgets表添加一个条目时,如何确保它链接到Items表中具有唯一ItemID的新条目? 我应该只跟踪ItemID而不是单独的类型特定ID,如WidgetID和DoohickyID,并使用它来创建Items表和类型特定表之间的一对一关系?
选项4
Items Table: ItemID (PK), Name, Size
Widgets Table: ItemID (PK), Color
Doohicky Table: ItemID (PK), Smell
有关它们的大量信息,请参阅经典的Martin Fowler书籍企业应用程序架构模式 。
您可以做的一件事是确保只有一个子类型可以引用超类型是使用ItemType
字段。 外键可以引用UNIQUE约束的列以及PRIMARY KEY。 因此,您可以添加Items.ItemType
并对ItemID
, ItemType
创建唯一约束。 每个子类型表中的外键引用此两列唯一键。 然后,您可以将每个子类型表中的ItemType
约束为特定值。 然后它必须匹配超类型表中的值,该表只能有一个值。
Items Table: ItemID (PK), ItemType, Name, Size
UNIQUE: (ItemID, ItemType)
Widgets Table: ItemID (PK), ItemType, Color
FK: (ItemID, ItemType)
CHECK: ItemType=W
Doohicky Table: ItemID (PK), ItemType, Smell
FK: (ItemID, ItemType)
CHECK: ItemType=D
如果您正在设计时考虑到当前的课程,我希望您选择3作为首选选项,原因如上所述。
重新查询:
However, I'm not sure how to create the relationship between the Items table and the
Widgets and Doohickies tables. I don't want to end up with row in either table
referencing the same ItemID in the Items table.
比尔的建议绝对是一个不错的选择。 我没有想到的东西:-)然而,我认为它是一种关系,你可以在你的应用程序代码本身或使用Insert触发器强制执行。
然而,我关心的是尝试在数据库级别模拟继承本身。
如果预计子类的数量会在一段时间内增长,那么这种数据库设计可能会变得非常难以维护。
此外 :
Items Table: ItemID (PK), Name, Size
Widgets Table: WidgetID (PK), ItemID (FK), Color
Doohicky Table: DoohickyID (PK), ItemID (FK), Smell
新课程的可能性如下所示?
DontDoHicky Table : DoohickyID (PK), ItemID (FK), Smell, **TASTE**
MidWidget Table : WidgetID (PK), ItemID (FK), Color , **Height**
MidDoHicky Table : WidgetID (PK), ItemID (FK), **Height**, **Smell**
这当然是经典的OO继承问题。 如果您希望应用程序在一段时间内像这样增长并且可能需要事先计划,在数据库级别,您可能更愿意采用更通用的方法
Items Table: ItemID (PK), Name, Size, **ItemType**
**ItemAttributes Table : ItemID (PK), AttributeID, AttributeName, AttributeValue**
这将允许您轻松地强制执行1:1映射约束,并允许您使用AttributeName轻松查询所有属性,只要这些属性是标准的。
这可能是老式的方法,并不是非常面向对象,但它可能更适合基于未来的灵活性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.