Database design 数据库设计-为报告目的复制列

Database design 数据库设计-为报告目的复制列,database-design,Database Design,我有以下表格: Product(ProductID, ProductName ...) ProductBidHistory(ProductID, UserID, Amount, Status, ...) BidHistory表可以增加到每个产品都有许多记录,我想要一个包含每个产品的已批准投标的报告,即status=approved的金额 是否可以在产品表中设置ApprovedAmount列,在投标结束时填充该列,以便于报告 应将报告写入到历史记录表中,以查找“已批准”并获取金额 复制列可以

我有以下表格:

Product(ProductID, ProductName ...)
ProductBidHistory(ProductID, UserID, Amount, Status, ...)
BidHistory表可以增加到每个产品都有许多记录,我想要一个包含每个产品的已批准投标的报告,即status=approved的金额

  • 是否可以在产品表中设置ApprovedAmount列,在投标结束时填充该列,以便于报告
  • 应将报告写入到历史记录表中,以查找“已批准”并获取金额

复制列可以吗?

这实际上取决于这些表的大小

如果它们不是太大,我建议您不要复制列,因为这将在应用程序层造成更多开销。一个简单的视图或用户定义的表函数就足够了。还要确保在正确的列上有索引


但是,如果表非常大(数百万行),那么您可能会看到通过存储用于报告目的的值来提高性能。

从纯设计的角度来看,您不应该保留相同数据的两个副本。这可能导致数据不一致。如果批准的金额和投标历史不一致怎么办


从性能角度来看,您可以复制数据以获得生成报告的加速


从应用程序的角度来看,开发人员必须确保在投标历史记录表中的每次更新中对产品表中的批准金额进行适当的更新。

通常,您不应该在关系数据库中重复列,这样就有可能根据(有效)查询的表达方式得到彼此不一致的答案

Approved不是产品的一个属性,而是投标的一个属性,您应该始终尝试让数据库结构反映真实世界的本体

当然,如果产品表中的行不是指某人拥有的特定产品(如iPad 16G s/N 123456789),而是指一般的“目录说明”产品(如iPad 16G),并且可能出现在多次拍卖中,则您不能在产品表中放入Approved yes/no(布尔值)列。不清楚你的简化设计是为了问你在这里想什么


在您的查询中,您永远不会简单地要求“所有已批准的投标”,而没有其他限定符。术语“approved=true”将始终与其他一些术语相关联,例如投标日期在?之后,或产品id=?,或(a、b、c)中的产品类别,这些术语可能是索引的候选列。因此,明智地使用索引,不要违反规范化规则,保持您的本体真实,您的数据库将照顾您。

为了澄清,如果Product:BidHistory==1:Many关系,那么一列如何满足要求?BidHistory是否只有1个状态=产品的已批准行?从性能角度来看:使用物化(SQLServer上的索引视图或Oracle上的物化视图,例如)。除此之外,该职位+1。设计透视图是最重要的。此外,如果您选择去规范化,确保数据保持一致的唯一方法是使用触发器。依靠应用程序来实现这一点是一个很大的错误。