2010-09-03 99 views
2

我正在设计一个跟踪订单的应用程序。每个订单可以有> 1个工作项目,每个工作项目可以有单独的价格。数据库设计:在哪里放置总金额字段

我在workItem表中存储了workItem的价格,认为在UI或报告中,收集工作成本(均向客户收费并支付给承包商)将通过查询workItems表中的现有数据。

以这种方式离开它还是将总金额存储在订单表中是否合理?如果我使用后者,是不是数据冗余?也许有这样一个举措的性能考虑。你怎么看?

回答

4

这取决于您的数据库如何使用。

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

有了合适的索引这样的查询通常是高性能:

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

话虽这么说,如果找到这个性能问题可能会非规范化的数据模型和存储总共为好。但是只有在需要的时候才能沿着这条路线走下去。在我看来,不应该先发制人。

+0

如果您在Order表中有价格,数据库将不会被标准化。如果出于某种特定原因需要这样做,您应该只会这样做,也许出于性能原因。如上所述,这取决于您的数据库如何使用。 – 2010-09-03 09:06:55

+0

@Tim:即使您存储了价格,您的数据库仍然可以正常化,它只是到不同的级别:http://en.wikipedia.org/wiki/Database_normalization – 2010-09-03 09:10:47

+0

是的,好的 - 所有这些评论完美无缺感觉...我真的很感激它。 – NinjaCat 2010-09-03 09:14:57

2

正如你所说,性能和使用是这里正确决定的关键。现在未来可能不会有什么正确的决定。

需求可能是列出所有仅显示总价值的订单。如果您不存储该值,则必须汇总每个订单的订单商品才能获得总计。如果您将此值与订单表一起存储,则不需要在表中包含订单项。

您也可以将此思路扩展到订单商品的数量。这个价值可以被计算出来,但是如果在概述中需要这个价值的话,那么可以获得很大的性能提升,就是将它存储在订单表中。

+0

是的,好的 - 所有这些评论都非常有意义......我真的很感激它。 – NinjaCat 2010-09-03 09:16:20

1

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

相反,根据报告或显示需要计算它。

2

如果遵循规范化规则,则会省略计算值,例如总计并在运行中生成它们。

但是,在某些情况下,您可能会选择稍微取消归一化并明确存储这些值。

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

在您的示例中,如果您按照订单存储总金额,则每次修改某个项目时都会碰到工作项表,并且您还必须更新订单表。这似乎没有什么好处,所以我不会走这条路......但正如我所说的,有些情况下你可能会明智地选择存储数据,而不是实时获取数据。

+0

是的,好的 - 所有这些评论都非常有意义......我非常感谢。 – NinjaCat 2010-09-03 09:15:37

+0

而且如果我决定取消这个总价值。是否有一个**存储过程**在'workitem'表中发生更改时更新总值是确保2个值在数据库级同步的一个很好的解决方案?或者我在PHP /应用层更新它? – 2018-02-22 13:34:31

+1

@Accountant你真的应该把这作为一个单独的问题。我的看法?如果你真的想去规范化,你很可能会使用AFTER触发器。然而,另一种选择通常可能是使用Computed Columns - 不幸的是,这些不能用于不同的表格,因此潜在的解决方法是创建(索引)视图。因此,不是将总计存储在发票表中,您可以创建一个发票视图,其中包含基础数据和计算的总计。 – CJM 2018-02-22 17:31:27