2010-02-08 56 views
1

抱歉如果標題不是很清楚。我將嘗試現在解釋:試圖設計一個應該從另一個表中總結數值的列

我有兩個表:表A和表B.它們之間的關係是一個(對於A表)對許多(對於B表)。所以,這就像主從情況。 我在表B中有一列'金額',很明顯是十進制的,表A中的一列'TotalAmount'。我試圖找出如何保持表A中的值爲最新。我的建議是根據表A製作一個視圖,用聚合查詢來計算表B的數量。當然,使用適當的索引... 但是,我的隊友建議每次我們改變一些東西時更新表A中的值在我們的應用程序中的表B中。 我想知道,這裏最好的解決方案是什麼?可能是第三個變體?

一些澄清...我們預計這個表是我們數據庫中增長最快的表格。而表B的增長要比表A快得多。表B中最常見的操作將是插入...並且幾乎沒有別的。表A中最頻繁的操作將被選擇...但不僅限於此。

回答

1

我看到了一些選擇:

  1. 使用上表B中的INSERT觸發器並做更新表A作爲你的朋友建議。這將使表B保持儘可能最新。
  2. 有一個計劃任務,每x分鐘更新一次表格(x =對您的應用程序有意義)。
  3. 更新表B時,在應用程序邏輯中的表A上執行更新。如果您在很多地方更新表B,這可能無法解決。
+0

選項2不適用於此,因爲我們需要始終保持最新狀態。但選項1聽起來合理。 – anthares 2010-02-08 09:07:13

1

如果您在應用程序中向表B插入新行的地方最簡單,那麼最簡單的解決方法是發送一個UPDATE A set TotalAmount=TotalAmount + ? where ID = ?並傳遞剛剛插入到B中的值。確保您包裝事務中的兩個查詢(插入和更新)都可以發生,也可以不發生。

如果這並不簡單,那麼您的下一個選項是數據庫觸發器。閱讀數據庫的文檔如何創建它們。基本上,觸發器是在DB發生某些事情時執行的一小段代碼(在你的情況下,當有人在表B中插入數據時)。

該視圖是另一種選擇,但它可能會導致選擇過程中出現性能問題,而這些問題很難解決。嘗試使用「物化視圖」或「計算列」(但這些會在插入/移除列時導致性能問題)。

1

如果這個值會發生很大的變化,那麼最好使用視圖:這絕對是更安全的實現。但更好的是使用觸發器(如果你的數據庫支持它們)

我猜你的隊友建議更新每個插入的值,因爲他認爲你會經常需要這個值,每次重新計算值。如果是這樣的話:

  • 你的數據庫應該照顧緩存,所以這可能不成問題。
  • 儘管如此,您可以在稍後的階段添加該功能 - 這樣您可以確保您的應用程序可以正常工作,並且可以更容易地調試該緩存列。
0

我肯定會推薦使用觸發器來使用應用程序邏輯,因爲這樣可以確保數據庫保持最新值,而不是依賴所有的調用者。但是,從設計角度來看,我會謹慎的將生成的數據與非生成的數據存儲在同一個表中 - 我認爲保持明確的分離非常重要,因此人們不會在應該使用哪些數據保持和維護他們。

但是,一般來說,更喜歡觸發器的意見 - 這樣你就不必擔心維護價值。配置文件來確定性能是否是一個問題。在Postgres中,我相信你甚至可以在計算的值上創建一個索引,所以數據庫不必查看細節表。

定期重新計算的第三種方法將比觸發器慢得多,並且可能比視圖慢。無論如何這不適合你的使用是蛋糕上的糖霜:)。

相關問題