Sql-Server

OLTP 索引視圖或 SQL 計算

  • November 12, 2017

在我們的金融公司,我們為客戶提供不同的 OLTP 交易。我們有一個交易表(借方、貸方)和余額表。我們每個月只有 1000 筆交易。

擁有帳戶餘額表的最佳方法是什麼?

1)一個人想使用索引視圖,因為我們有相對靜態的數據。

  1. 我想在 sql 程式碼中計算賬戶餘額。我不想處理有時在執行計劃中不使用索引視圖的查詢問題、更新期間的死鎖、更新/刪除數據時的複雜執行計劃等。更喜歡報告/Olap 數據庫的索引視圖。

並發事務數據庫是否有正確答案?在小型事務性 oltp 數據庫中使用索引視圖時需要注意什麼問題?

create table dbo.AccountTransaction
( AccountTransactionId int primary key identity(1,1),
 CustomerId int null,
 TransactionAmount money not null )

create table dbo.AccountBalance
( AccountBalanceId int primary key identity(1,1),
 CustomerId int null,
 BalanceAmount money null )

SQL計算方法:

begin transaction
   insert into AccountTransaction 
   values(@CustomerId, @TransactionAmount)

   update AccountBalance
   set BalanceAmount = BalanceAmount + TransactionAmount
   where CustomerId = @CustomerId

end transaction

索引視圖方法:

create view dbo.AccountBalanceVw
with schemabinding
as
select
   customerid,
   sum(transactionamount) as BalanceAmount,
   COUNT_BIG(*) AS CountLines
from dbo.AccountTransaction
group by customerid

create unique clustered index cx_AccountBalanceVw on AccountBalanceVw(CustomerID); 

這是一個非常開放的問題,你沒有透露的許多因素可能會改變人們的看法。

那就是說;在我的職業生涯中,我不得不處理類似的情況。

要獲得目前餘額,您需要匯總所有交易。這導致在使用 SQL Server 時,索引視圖是正確的解決方案。它確實是一個很好的,但是,它並非沒有局限性。您需要考慮以下因素:

  • 如果我有索引視圖,架構更改會對我造成多大的影響?
  • 我需要刪除索引並重建它嗎?
  • 多久才能做到?
  • 在重建期間,我能否承受基表上的阻塞?
  • 我的索引視圖是否會阻止以後重構事務表?

這些可能會成為您未來應用程序開發的相當大的障礙。

由於這些(我相信還有其他)因素,您可能會開始傾向於“即時”計算餘額。也就是說,您基本上有自己的觀點,但沒有索引。或者只是查詢表並對事務求和。如果您開始研究這種方法,您必須考慮:

  • 每個賬戶會有很多交易嗎?
  • 如果我們這樣做,餘額查詢會執行嗎?
  • 計算餘額是否會以任何方式影響其他查詢(特別是添加新事務)(在這裡考慮阻塞)

您已經給出了在數據更新時計算和儲存餘額的第三個選項。這似乎很有吸引力,因為它避免了我所介紹的前兩種情況的所有缺點。您可以快速查找,並且我的架構不會受到阻礙或與索引視圖相關聯。這裡也有一些陷阱:

  • 每次更新表格時是否都要手動計算新余額?
  • 我是否使用觸發器來保持平衡(並避免上一點)
  • 我是否必須同時處理被刪除或更新的行(提示:你會……即使你認為你不會)
  • 我能否承受我創建的任何觸發器對性能的影響?它的好處是否超過了這個成本?

我們甚至還沒有考慮過事務隔離級別!您將使用 READ COMMITTED SNAPSHOT 或 SNAPSHOT ISOLATION 嗎?因為這些有你需要考慮的影響。

根據您提供的資訊,我可能會做什麼

您提到您每月只期望 1000 筆交易。作為更糟糕的情況,我將把它理解為每個客戶每月 1000 個。這並不是很多數據,尤其是在早期。誠然,如果您有 1,000,000 名客戶都在進行 1000 次交易,那麼您將擁有大量數據。我也假設少數客戶。

我不會為餘額使用索引視圖或計算表/列而煩惱。我只是在執行中查詢它開始。通過這種方式,您可以增強和擴展您的架構,而不必擔心其他選擇可能產生的影響。

從長遠來看,隨著模式的穩定和應用程序的成熟,我會查看其他兩個選項,看看哪個最適合案例。我喜歡索引視圖可以給你的東西,但是,它們並非沒有缺點,而且當你以後想要進行更改時可能會很痛苦。

這種方法遵循應用程序程式中可能面臨的“過早優化”問題。您不能總是通過數據庫設計來做到這一點,但是,我認為您可以在這裡進行,因為您以後可以進行的優化非常容易。特別是如果您在開始時通過視圖抽象平衡檢索。無論您以後採取何種方法,您只需更新該視圖以從新對像中檢索數據。

稍微偏離主題:

您的架構的幾個提示(我也知道您可能已經為這個問題簡化了它)

  1. 您的架構顯示每個客戶的交易列表。這表示每個客戶都有一個且只有一個帳戶。今天可能就是這種情況,但是,我強烈建議您設計您的架構以容納每個客戶的多個帳戶。
  2. 我不建議使用金錢數據類型。它沒有足夠的精度或規模。通常在處理財務數據時,您可能需要精確到小數點後 6 位,具體取決於貨幣。或超出貨幣數據類型的最大大小。

引用自:https://dba.stackexchange.com/questions/190706