假设您有两组概念实体:
两个不同的子对象都有几乎相同的字段:
ForwardPriceEntry有
PoolPriceForecastEntry有
如果我将它们建模为单独的表,唯一的区别是外键和价格字段的名称。
关于两个几乎相同的表是否应合并为一个,存在争议。
我想到的模型选项是:
你认为我应该做什么,为什么?
可能相关或不相关的其他信息:
两组数据松散相关:每组数据将被加载到内存中进行批处理,偶尔会从复制生成一组 PoolPriceForecastEntries ForwardPriceEntries
MarketPriceDataSet 和 PoolPriceForecastDataSet 确实有不同的字段。可以将它们合并到一个表中,但是在一半的条目中你会有无意义的字段。
答案 0 :(得分:3)
通常,在您描述的情况下,被建模的主题符合称为“泛化专业化”的模式。两个先前的答案讨论子类型的事实支持这一点。对象模型倾向于通过使用子类型和继承来处理gen-spec。
关系模型也可以处理gen-spec,但它更复杂,并且通常不会在数据库引物中教授。你所做的是有几个表,每个子类型一个,保存子类特有的键和非键属性。与超类型相关并由所有子类型继承的数据通常合并为一个表。
您可以使用这些表的键来减少存储和处理。在子类型表中,使用外键返回超类型条目作为子类型表的主键。它保证存在,并保证是独一无二的。为什么还要发明另一把钥匙?
如果您搜索“泛化专业化关系建模”,您将获得关于该主题的十几篇文章。其中一些非常好。您还可以点击标记:class-table-inheritance
答案 1 :(得分:3)
“关于两个几乎相同的表格是否应合并为一个,一直存在争议。”
有吗?
在数据库设计中,如果表的谓词不同,则表应保持独立。也就是说,如果附加到表中的行的含义不同。列的集合是否几乎或甚至完全相等,是无关紧要的。
答案 2 :(得分:1)
由于实体共享如此多的属性,您可以将它们视为子类型。
逻辑上,您将拥有PriceEntry的超类型以及ForwardPriceEntry和PoolPriceForecastEntry的子类型。要回答的一个问题是价格是否与超类型相同。我会假设它是。
现在的问题是如何物理实现子类型。您可以采取以下三种方法:
这些方法中的每一种都有利有弊。有关每种方法的利弊的讨论,请参阅Getting Physical with Subtypes。
在这种情况下,由于子类型共享许多属性,因此您可以采用汇总方法并创建单个表。
PriceEntry表可能如下所示:
PriceEntryId (PK)
PriceEntryTypeCode (NN)
StartDate (NN)
EndDate
SimulationItemId (NN)
Price (NN)
MarketPriceDataSetId (FK)
PoolPriceForecastDataSetId (FK)
您仍然可以在MarketPrice和PoolForecast列上强制执行FK。您还可以添加表级检查约束,以确保至少填充一个FK。
然而,由于两个子类型之间只有一个属性不同,因此许多优点和缺点并不强烈指向一个方向。因此,最后,我可能会选择保持数据模型易于理解和使用。对我来说,两个表(rolldown)方法达到了很好的平衡;从概念上讲,它比汇总更容易理解,开发时比身份更容易使用(没有连接或多次插入/更新)。
答案 3 :(得分:0)
如果您打算以大致相同的方式使用两个子类型的数据,我建议将所有数据放入一个包含所有五个字段的表中......
...并将null放入ForwardPrice或ForecastPoolPricedepending字段,等待特定行支持的父实体。每行上空值的空间成本几乎不存在,压缩成功在表上非常高,但对于索引和读取,您的性能会令人印象深刻。