【问题标题】:Database subtyping/supertyping数据库子类型/超类型
【发布时间】:2013-06-07 23:52:55
【问题描述】:

我有表“作物”、“玉米”、“大豆”和“谷物”。 Crop 中的一个条目对应于其他表之一中的单个条目。这里的问题是 Crop 应该与其他表中的一个是一对一的,但不能超过一个。需要 Crop 表是因为它结合了其他表中的许多公共数据,并使查询信息在代码方面变得更加容易。通过研究这个,我有几个有缺点的策略......

A.将三列放入 Crop 以获取其他表的 ID,然后填充“Corn”列(如果它是玉米作物等)...

缺点:浪费列,每当我想查看它是什么作物时,都必须检查所有三列

B.将 Corn、Soybean 和 Grain 表组合在一起,并添加一列来说明它是什么类型的作物。

缺点:每个表都有不同的列,每行浪费和不必要的列

可以说我被困在这里了吗?还是有处理此类案件的策略?谢谢。

【问题讨论】:

  • 这就是视图的用途。为您想要检索数据的每种不同方式定义一个视图,无需重复或浪费。
  • @Jesse 我不同意。当您希望能够拥有只能绑定到其中一种类型的 FK 约束时,唯一的解决方案是 1_CR 的答案中给出的超类型/子类型模式。视图不会起作用。

标签: sql-server database-design class-table-inheritance


【解决方案1】:

这是“子类型”情况,在 Stephane Faroult's the Art of SQL 中有广泛的介绍

推荐的解决方案包括在所有表CropCornSoybeanGrain 中使用相同的唯一键(在本例中为CropID)。然后Crop 表的主键集合成为CornSoyBeanGrain 的主键的联合。此外,您在Crop 表上定义一个属性,例如CropType,指示每个Crop 记录的类型。 这样,公共属性保留在 Crop 表中,特定类型的属性转到特定类型的表中,没有冗余。

【讨论】:

  • 除非您也将CropTypeID 放入子类型表中,否则您可以获得不同步的数据。添加该列还可以让您对CropID, CropTypeID 上的超类型表使用复合FK,这在物理上强制您不能将相同的CropID 插入多个子类型表中。我还建议在子类型表中将其称为 CornIDSoyBeanIDGrainID——因为在其他使用 FK 的表中,当 FKing 到超类型时使用 CropID,而当 FKing 到时使用 {Subtype}ID子类型之一。
  • 太棒了。我知道肯定会有其他人处于这种情况。甚至学会了一些新的词汇。我已重命名主题以反映这一点,并确保其他人可以看到您的答案。
  • 这种模式在class-table-inheritance的信息标签中也有描述
【解决方案2】:

为什么不为所有表提供数据透视表,例如:

 PivotTable -> PivotID, PivotDate
 Crop->CropID, PivotID, other fields
 Soybean->SoybeanID, PivotID, other fields
 Gran->GrainID, PivotID, other fields

因此,您可以选择只有一个 PivotID 的所有表

【讨论】:

  • 您可能会考虑重新阅读要求——我认为这不符合要求。
  • 感谢您的评论@ErikE。但我认为这与接受的解决方案相去甚远,除非在我的情况下,我有一个单独的表可以处理所有子类型,而接受的表中有一个表,即 Crop。除此之外,这可以很容易地采纳您的建议,其中子类型表的所有 FK 都可以在一个表中,因此如果您想专注于一个子类型,您可以这样做。虽然在我的情况下,我可以把它放在我的数据透视表上。顺便说一句,这就是 SO 的美妙之处,您冒着提出解决方案的风险...
  • ...最好的一个通常被接受,而我的恰好不是一个。此外,我通常会看到作为入门的答案并进行相应编辑以增强或适应扩展的要求。
猜你喜欢
  • 2011-12-05
  • 2012-08-28
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
  • 2012-01-22
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多