1

假設Order有很多Line項目,我們將在訂單表中存儲訂單的總成本(基於訂單行上的價格總和)。必須插入一條記錄,然後更新相同的記錄權證1:1關係設計?

-------------- 
orders 
-------------- 
id 
ref 
total_cost 
-------------- 

-------------- 
lines 
-------------- 
id 
order_id 
price 
-------------- 

在一個簡單的應用程序中,訂單和行是在結帳過程的同一步驟中創建的。所以這意味着

INSERT INTO orders .... 

-- Get ID of inserted order record 
INSERT into lines VALUES(null, order_id, ...), ... 

我們在創建訂單記錄後得到訂單ID。

我遇到的問題是試圖找出最好的方式來存儲總成本的訂單。我不希望有

  1. 創建訂單
  2. 基礎上再行更新記錄在1中創建的訂單表
  3. 計算成本上訂單的上創建行

這意味着可爲空TOTAL_COST領域的訂單對於初學者...

我的解決方案迄今是有一個order_totals表1:1的重請撥訂單表。但我認爲這是多餘的。理想情況下,因爲計算總成本(訂單上的行)所需的一切都在數據庫中,所以我會在每次需要時計算出該值,但這非常昂貴。

你有什麼想法?

回答

2

我會迴應其他答案並說,除非這樣做的代價太高,否則我會根據需要計算lines表的總成本。

或者,可以定義適當更新orders.total_cost的觸發器。然而,需要對linesINSERTUPDATEDELETE定義觸發器:

CREATE TRIGGER after_insert_lines AFTER INSERT ON lines FOR EACH ROW 
    UPDATE orders SET total_cost = total_cost + NEW.price; 

CREATE TRIGGER after_update_lines AFTER UPDATE ON lines FOR EACH ROW 
    UPDATE orders SET total_cost = total_cost - OLD.price + NEW.price; 

CREATE TRIGGER after_delete_lines AFTER DELETE ON lines FOR EACH ROW 
    UPDATE orders SET total_cost = total_cost - OLD.price; 
+0

當然,如果你存儲彙總數據,你必須有觸發器,以確保它始終保持正確的。依賴於此應用程序是一個非常糟糕的選擇,因爲可以通過多種方式更改數據。 – HLGEM

+0

觸發器是一個有趣的選項,謝謝。 – dianovich

3

我認爲最好不要訂單總計專欄或表格。

只要您需要顯示訂單總額,只需計算訂單總額即可。想象一下,如果行記錄更改,那麼您將不得不不斷維護另一列或表以更新訂單的總價格。

3

該表不是必需的,因爲它可以存儲爲訂單表的一列。

是否值得將它作爲新列存儲取決於您將讀取值與所做更改(以及計算成本)的次數。

如果它被讀了很多,但沒有經常更改,並且需要不可接受的時間來計算,那麼值得維護一個新的總列。否則,您最好每次都計算一次,也許通過視圖進行計算,這樣您就不必在所選的任何位置進行計算編碼。

2

我同意其他評論者的觀點,除非通過資源明智地計算訂單項的總費用,否則最好使用SUM/GROUP BY查詢來完成此操作。

但是,如果您仍然想要使用前期總成本計算,只需在開始運行SQL插入之前在內存中進行計算即可。畢竟,您需要將數據插入到訂單項中,因此只需對它們進行迭代,然後總計總成本,然後使用總成本創建訂單記錄。跟隨該行項目插入。

2

正如其他人所建議的那樣,最好在飛行中計算總和。

我只是想補充一點InnoDB clusters its tables,所以如果你選擇的PK上lines正確,同一順序的線將被存儲物理上接近在一起,你就可以計算整個總和以最小的I/O(即非常快)訂單。

爲此,請放棄lines中的替代PK,並使用天然PK:{order_id, line_no}