2010-06-25 53 views
1

在我們的庫存數據庫(SQL Server 2008的STD版)我們有一個表(稱爲股票結果),存儲結果爲每個股票項目通過股票期權,這看起來像這樣:是否正常化成績表或不

<<StockResults>> 
PK StockPeriodID int 
PK StockItemID int 
OStockCost money 
OStockQty real 
DeliveriesQty real 
CreditsQty real 
TransfersInQty real 
TransfersOutQty real 
CStockQty real 
OStockAmt money 
DeliveriesAmt money 
CreditsAmt money 
TransfersInAmt money 
TransfersOutAmt money 
CStockAmt money 
... except that it has about 40 columns 

我們正在考慮規範化該表,以便我們有一個表和一個數據表。就像這樣:

create table StockResults_Fields 
(FieldID int, FieldName varchar(20), FieldDataType varchar(10)) 

create table StockResults_Values 
(StockPeriodID int, StockItemID int, FieldID int, FieldName varchar(20), FieldDataType varchar(10)) 

我們正在考慮這樣做的原因是爲了改善表的性能並防止死鎖(我們目前收到)。關於規範化以減少死鎖的建議來自本文:Reducing SQL Server Deadlocks

我的擔憂是結果表(它已經很大)會變得更大。大多數報告顯示的數據結構與當前結構相似 - 新方法將會有更多的連接。

在我們開始涉及相當多的工作之前,有沒有人對我們開始之前的結果和性能優勢的這種規範化結構有任何建議?

編輯:感謝您的建議。我有一種直覺,認爲2桌方法並不是一條可行的路線,但我不確定爲什麼 - 直到現在。鎖定錯誤已經解決:我們有一個沒有聚集索引的表,但快照隔離看起來像我們可能考慮的。

+0

@Phil和@RedSquare都有很好的建議。 1)不要移動到元數據模型。這種方式是瘋狂和cthulu。 2)考慮創建一個靜態存儲,偶爾用實際值刷新以減少爭用(即隔離層)。 – 2010-06-25 18:38:27

回答

7

聽起來好像你知道所有在設計系統時需要的列。如果是這樣,你應該絕對不是繼續你提出的設計。

這種設計的唯一可能原因是,如果您不知道設計時需要的所有字段,並且需要在生產後添加一些字段。

我會預測你的雙表法會比現在的方法表現得差得多。另外,這與標準化無關,至少在我的定義中是如此。你會做的是從關係模型轉向元數據模型。

(編輯:你也應該發佈有關死鎖發生的時間/地點的更多信息,如果這是你試圖解決的問題的根源)。

+1

+1。我們使用存儲名稱/值對的表進行大量開發。我只是簡單地說,如果報告結構已經使用了所有這些字段,並且您已經知道系統設計中的列,那麼不要走這條路。它有它自己的性能問題,並且通常需要一些嚴格的DBA經驗才能正確執行。 – NotMe 2010-06-25 18:38:35

2

您可以先嚐試將數據庫更改爲Snapshot Isolation級別,以查看這是否可以減少爭用\鎖定。我最近做了一個MS Dynamics安裝(有很多列的大表),它已經工作過一次(是的,我首先得到了微軟的支持!)。如果它有效,它將比你的表重構提議更快得多。

+0

感謝您關於snaphot隔離的建議。 – 2010-07-01 12:14:21

+0

@ craig-hb您是否解決了您的問題,我會對您做過什麼/嘗試過以及哪些方面有效。 – redsquare 2010-07-01 12:44:06

+0

啊我現在在編輯中看到它。 – redsquare 2010-07-01 12:44:39

0

您可能可以擺脫這裏的死鎖問題,但爲了提高性能,您是否嘗試將表分區爲單獨的spindels? 您也可以按照紅色方塊的說法更改快照隔離級別,或者如果您不希望所有查詢具有相同的隔離級別,則可以將WITH(NOLOCK)添加到SELECT查詢中

1

我想你會遇到死鎖的原因之一是你試圖在表中做太多,並且需要規格化的子表,而不是你所建議的(這不是通過任何伸縮規範化數據)(請閱讀http://www.simple-talk.com/opinion/opinion-pieces/bad-carma/,爲什麼你的建議是一個壞主意)。

在我看來,你的表結構不斷更新,因爲它總結了數據。將更改數據放入單獨的行中,然後彙總到僅定期更新的報告或數據倉庫中。或者甚至在視圖中進行彙總。但是不通過視圖來更改數據表。

因此,我將有一個庫存表來定義股票的部件編號和描述性細節,然後爲每種類型的數據隨時間變化而定義一個子表。

因此,stock_transaction表將以股票ID和項目數量開頭 如果您收到一塊新股票,它會添加一條記錄,並顯示收到的總數。然後,如果您發出一個項目,它會添加一個項目數等於-1的記錄,然後找到您總結數據的項目總數。要查找已發佈的庫存項目總數,您可以對負值進行求和並取絕對值)這是我工作的大多數倉庫庫存應用程序的工作方式。此外,您還有其他字段,以便您可以跟蹤股票的交易日期和交易日期,以便您可以在細節級別查看總體情況。

現在,如果不能更好地瞭解整張桌子,以及檔案的含義和填充方式,我無法建議可能需要創建哪些子表。但是,如果將數據分離爲自然的子記錄,則應該有更少的死板和更糟的定義。試想一下,如果數據需要經常更新,那麼該字段就是子表的候選人。您可能可以將幾個當前的字段分組到子表中,這取決於信息的相關程度。

但是,像這樣的重組是一項重大的努力,需要花費很多時間來完成並遷移和測試數據以及應用程序更改。如果您現在可以通過分區或使用其他人所建議的快照隔離功能來獲得更好的性能,那麼這種事情就會成爲現實。如果你獲得了更好的表現,但不夠好,那麼重新設計,但是使用其他技術來改善表現,而你花費了一整年的時間,這將需要重新設計。我只是提出這個建議,以防萬一你無法通過其他方式解決性能問題,以顯示你真正規範化數據的方式,並讓你瞭解遵循這條路徑會有多昂貴。

+1

你說得對。 OP正在做的事情不能被視爲正常化。 – 2010-06-26 10:39:04

+0

你鏈接到的偉大的文章!可憐的老蘭迪和他的數據庫終止所有數據庫。 – 2010-06-30 22:03:09