两个不同的表或只有一个与bool列?

时间:2010-03-29 14:14:02

标签: sql database database-design null

我们有两个表:OriginalDocument和ProcessedDocument。在第一个中,我们放置了原始的,未处理的文档。在验证和处理(转换为我们的XML格式并解析)之后,它被放入ProcessedDocument表中。已处理的文档可能有效或无效。 哪个更有意义:有两个不同的表用于有效和无效的文档,或者只有一个有'有效'列?有些列(~5-7)与无效文档无关。存储无效和有效文档也会使Document表填充'NULL'列(如果文档无效,文档编号,接收器等信息可能是未知的)。在做出这个决定时,我们还应该考虑和权衡什么?

7 个答案:

答案 0 :(得分:6)

无论文档是有效还是无效,它仍然是一个文档,因此它们在同一个表中都具有初步意义。

但是,如果您的应用程序对无效文档的处理方式不同(即未查询,更新等),则将表格拆分。将这两种类型的文档放在同一个表中只会减慢您的查询速度而不会立即受益。

我有一个文档表,其中有效和无效文档保存在一起,但仅仅是因为应用程序将错误文档重新呈现给用户并要求他们修复它。

答案 1 :(得分:5)

对我而言,听起来有点列是有意义的,因为所有文件都已经过实际处理,只是有些已被确定为无效。根据列数,如果您只有5个左右的10-15列不适用,则无需为同一数据管理两个结构。

现在,您可以看到的另一件事是您是否需要同时定期获取有效和无效文档的信息?如果是这样,那么你真的希望它在一张桌子里。

如果您不需要一起查询它们,或者文档是“无效”,除了历史记录之外不再需要它,那么将它移动到自己的表中是有意义的。

答案 2 :(得分:3)

答案 3 :(得分:2)

尝试区分逻辑和物理建模。

即使两个实体之间的差异只有七个属性,它们在这七个项目中在逻辑上是不同的。 与此同时,它们在其他属性中也是一样的。

逻辑上表示的方式是这两个表之间有一对一或零关系,并且一个表存储所有公共属性(超类)而另一个(子类)只存储存储超类中的ID。

就性能而言,这并不是那么糟糕:

  • 当您不关心使用何种类型的文档时,您将查询超类表(增益)
  • 当你知道你只想要在子类表中找到的特定属性时,你只能使用那个表(这可能是真正的好处)
  • 只有当您需要加入两个表时才会付出代价(连接的价格与非规范化结构相比,例如将所有内容存储在一个表中)
  • 您还需要在插入子类记录时付出代价,因为您将插入两个表(这可能非常低和/或证明合理)

根据您正在建模的流程,这些查询的频率和其他内容(例如实体的安全性,所有权,完整性规则的差异),您可能决定将此信息存储在数据库的一个表中或两个表中(要么在边界线情况下要快得多,并且两个表解决方案也可以进行非规范化处理;例如,您仍然可以在主表中存储有关文档类型的信息,以避免在这种查询是全部的情况下进行连接你在乎)。

或者您的实施决策可能是由您选择的应用程序框架驱动的,因此您可能更喜欢使用单表或其他方式(例如在django-admin等框架中自动创建数据输入表单) )。

无论你做什么,都要意识到逻辑和物理设计之间的区别。在你的逻辑设计中规范化一切 - 它会得到回报。在物理实现中,制作不同的场景 - 使用您自己的数据进行测试,测试和测试。永远不要混淆两者的顺序(逻辑概念和物理实践建模)。

答案 4 :(得分:1)

您的查询形状是什么?您是否经常希望处理一组(所有?)文档,无论它们是否有效?或者每个查询只检查每个有效(或无效)文档。

或者您希望与团体打交道(不论其有效性),但希望经常使用有效文件进行额外的工作。这可能指向一个基表和一个包含有效文档列的附加表?

答案 5 :(得分:1)

将OriginalDocuments视为中间表。它可以在您输入格式更改时更改。它将包含对导入(“已处理”)文档无效的字段,如导入日期或导入错误描述。你可以定期清理这张桌子。

与OriginalDocument相反,ProcessedDocument表将仅包含对您的系统有效的文档和字段,以及所有检查约束,索引和关联的业务逻辑。它的结构会随着系统内部逻辑的变化而改变。

答案 6 :(得分:1)

您可能需要考虑的另一件事是行的生命周期和用例。如果定期清除无效文档,则将它们放在单独的表中可能会有所帮助。如果无效文档的属性保持有限,但有效文档正在获得新列,那么这也是支持单独表的一个因素。由于实体在行为和使用方面越来越不同,因此有更多迹象表明单独的表是值得的。

相关问题