Database design 数据库设计:总金额字段的放置位置

Database design 数据库设计:总金额字段的放置位置,database-design,Database Design,我正在设计一个跟踪订单的应用程序。每个订单可以有>1个工作项,每个工作项可以有单独的价格 我在workItem表中存储workItem的价格,认为在UI或报告中,收集作业成本(向客户计费和向承包商支付)将通过查询workItems表中的现有数据进行计算 这样做有意义吗?还是将总金额存储在订单表中?如果我选择后者,数据不是多余的吗?也许这样的举动有性能方面的考虑。你怎么看?这取决于数据库的使用方式 理想的解决方案是在工作项行中保留单独的项。这样可以避免重复数据。例如,当添加或更新工作项时,否则必须

我正在设计一个跟踪订单的应用程序。每个订单可以有>1个工作项,每个工作项可以有单独的价格

我在workItem表中存储workItem的价格,认为在UI或报告中,收集作业成本(向客户计费和向承包商支付)将通过查询workItems表中的现有数据进行计算


这样做有意义吗?还是将总金额存储在订单表中?如果我选择后者,数据不是多余的吗?也许这样的举动有性能方面的考虑。你怎么看?

这取决于数据库的使用方式

理想的解决方案是在工作项行中保留单独的项。这样可以避免重复数据。例如,当添加或更新工作项时,否则必须同时更新工作项和总计

使用适当的索引,这样的查询通常会执行:

SELECT i.*, SUM(wi.amount) total
FROM invoice i
JOIN workitem wi ON i.invoice_id = wi.invoice_id
GROUP BY i.invoice_id

这就是说,如果您发现这方面存在性能问题,您可能会对数据模型进行非规范化,并存储一个总计。但只有在你需要的时候才走这条路。在我看来,这不应该先发制人。

正如你所说,性能和使用是正确描述的关键。现在正确的定义可能不会在将来

可能需要列出仅显示总价值的所有订单。如果不存储该值,则必须对每个订单的订单项进行聚合,以获得总计。如果将此值与订单表一起存储,则不需要在表中包含订单项


您也可以将这种想法扩展到订单项目的数量。该值是可以计算出来的,但如果在概述中需要,只需将其与orders表一起存储,就可以获得较大的性能增益。

除非性能成为问题,否则我不会将总数存储在数据库中


而是根据报告或显示的需要动态计算

如果遵循归一化规则,则会忽略计算值,例如总计,并动态生成它们

然而,有时您可能会选择稍微去规范化并显式存储这些值

就存储空间而言,如今在大多数平台上,存储空间通常不是问题,因此存储额外数据也不是问题。有时,当以这种方式进行反规范化时,您可以提高性能或简化代码。同样,您的决策也会影响可维护性,或者可能会增加复杂性


在您的示例中,如果您根据订单存储总计,则每次修改项目时,您都会点击workitem表,然后还必须更新订单表。这似乎没有什么好处,所以我不会走这条路。。。但正如我所说,在某些情况下,您可能会明智地选择存储数据,而不是动态派生数据。

如果订单表中有价格,则数据库不会正常化。只有在出于某些特定原因(可能是出于性能原因)需要时,才应该这样做。如前所述,这取决于数据库的使用方式。@Tim:即使您存储了价格,您的数据库仍然可以正常化,这只是到了一个不同的级别:是的,好的-所有这些评论都很有意义。。。我真的很感激。如果我决定去规范化这个总值。每当workitem表中发生更改时更新总值的存储过程是否被认为是确保两个值在数据库级别同步的好解决方案?或者我在PHP/应用层更新它?是的,好的-所有这些评论都非常有意义。。。我真的很感激。如果我决定去规范化这个总值。每当
workitem
表中发生更改时更新总值的存储过程是否是确保两个值在数据库级别同步的好方法?或者我在PHP/应用层更新它?@accountaryم你真的应该把它作为一个单独的问题发布。我的看法?如果你真的想去规范化,你很可能会使用AFTER触发器。然而,另一种方法通常是使用计算列——不幸的是,这些列不能跨不同的表工作,因此一种潜在的解决方法是创建一个(索引)视图。因此,您可以创建一个包含基础数据和计算总数的发票视图,而不是将总数存储在发票表中。@CJM非常感谢您的时间,先生,我非常感谢您的回答。是的,好的-所有这些评论都非常有意义。。。我真的很感激。