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和/或创建它更容易特定类型的项目(小部件或Doohickies)的列表。
但是,我不确定如何在Items表与Widgets和Doohickies表之间建立关系。我不想最后一个表中的行引用了Items表中的相同ItemID。
例如,当我向Widgets表中添加条目时,如何确保它以唯一的ItemID链接到Items表中的新条目?我是否应该只跟踪ItemID,而不是分别跟踪特定于类型的ID(如WidgetID和DoohickyID),并使用它在Items表和特定于类型的表之间创建一对一关系?
选项4
Items Table: ItemID (PK), Name, Size
Widgets Table: ItemID (PK), Color
Doohicky Table: ItemID (PK), Smell
#1 楼
您正在描述单表继承,具体表继承和类表继承。请参阅经典的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
#2 楼
如果您在设计时考虑到当前的类,出于上述原因,我希望将选项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触发器来实现。
但是我担心
如果子类的数量预计会在一段时间内增长,则这种DB设计可能会变得非常难以维护。
除了:
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**
这当然是经典的面向对象继承问题。 ,您可能更喜欢采用更通用的方法
Items Table: ItemID (PK), Name, Size, **ItemType**
**ItemAttributes Table : ItemID (PK), AttributeID, AttributeName, AttributeValue**
,这将使您轻松实施1:1映射的约束,并允许您使用A只要这些是标准名称,就可以使用ttributeName。
这可能是老式的方法,不是非常面向对象的,但根据将来的灵活性,它可能更适合。
评论
嗯,这很有帮助。我绝对希望遵循“类表继承”模式。
–埃里克·阿纳斯塔斯(Eric Anastas)
2010-09-14 22:31