簡體   English   中英

在數據庫中存儲計算量的正確方法是什么?

[英]What is the proper way of storing calculated amounts in database?

我有3個表( customersinvoicesinvoice_items )。

一個客戶可以有多個發票,一個發票可以有多個項目。

這是我當前的模式:

顧客

id
name
timestamps

發票

id
customer_id
timestamps

invoice_items

id
invoice_id
price
timestamps

注意:時間戳記created_atupdated_at字段。 不用擔心。

如您所見,我沒有在發票表中存儲發票的總額。 我讓前端進行計算。

現在,我的客戶有1000多個客戶,他們希望在首頁中顯示所有客戶以及他們所有發票的總和。

ID | 客戶名稱| 總發票(所有發票的總和)

現在我正在使用Laravel,所以查詢如下:

$customers = Customer::with('invoices.items')->get();

最好的方法是什么? 性能明智?

我是否應該只將每張發票的總金額存儲在發票表中以避免查詢項目和計算金額? 就像是:

發票

id
customer_id
total
timestamps

想象一個客戶有數千張發票,每張發票有多個項目。 查詢將非常慢,我必須計算前端的所有內容。

另外,開具發票后將無法更改。 因此,發票的總額是靜態的。

除了時間戳,它看起來不錯。 您不僅可以在發票表中使用一個時間戳列嗎?

為什么在所有3個表中都需要同一列?

另外,我確定您可以在php腳本中計算總數。 您不需要將可以通過count()計算的總數存儲在php中。

當然,當您在invoice表上添加total列時,您應該可以提高性能,因為您不必遍歷所有invoice_items並將它們加起來。 如果您只需要一次將項目添加到invoice中並且以后不需要更新,則這很好。 這樣,您將需要在一次生成發票的同時添加總計。

在發票表中添加total列絕對可以提高性能,也有助於通過雄辯的方式獲取結果。 但是,如果性能在這里並不重要,那么我們可以不用它來做到。 您的SQL查詢應該像(可能需要很少的調整)

SELECT c.*, i.*, sum(ii. price) as total_invoice_price
FROM customers c
INNER JOIN invoices i on i.customer_id = c.id
INNER JOIN invoice_items ii on ii.invoice_id = i.id
GROUP BY i.id

通過SQL獲得預期的結果后,可以使用laravel中的DB::table運行它。

這是WORM(多次寫入)的經典案例。

讓我們來看看這兩種方法的利弊:

  • 情況1:未將總計存儲在發票表中

    • 優點:簡單易用。 無數據冗余。
    • 缺點:每次計算總數時,性能降低並消耗資源(內存和cpu)
  • 情況2:將總計存儲在發票表中

    • 優點:性能更好,因為“復雜”發票的總計算僅發生一次,並且后續讀取速度更快
    • 缺點:數據冗余,需要一些額外的存儲

現在,如果您研究這兩種方法的弊端,情況2顯然更好,因為可以輕松購買額外的存儲,但是即使將RAM和CPU增加到一定程度也無法實現性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM