2010-09-03 98 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