0

我有一個旨在存儲賽馬時間的數據庫。目前,我有一個Race表和一個RaceTimes表。每個都有5個小數時間和5個拆分時間。 RaceTime表還包含一個Race外鍵。在SQL Server表中存儲規範化數據有哪些優缺點

例如:

RaceTime表:

RaceTime_id (primary key) 
    Race_id (foreign key) 
    TimeValue (time stored in 100th of seconds) 
    PointOfTime (i.e. 1/4 mile, 1/2 mile, etc.) 
    Which (where which is an integer between 1 and 5) 

鑑於有五次,每個種族分裂5,這種方法產生10個RaceTime記錄每場比賽。或者,我可以創建一個數據庫結構,其中包括:Fraction1,Fraction2 .... Fraction5和Split1,Split2 ... Split5。在這種方法下,Race記錄和RaceTime記錄之間會有1對1的匹配,而RaceTime表的行數會少得多。

我的閱讀和研究讓我相信第一種方法更可取。我相信這些數據更加正常化。我想我有一些暫停,因爲桌子大小的差異,但也許它只是一個長桌或寬桌之間的折衷。

這就是說,我希望從那些更加精通這些事情的人那裏得到意見,我只是一個喜歡玩馬的會計師。感謝您的輸入。

+0

「我只是一個喜歡玩馬的會計師」,並正在實施一個SQL表來幫助?主席先生/女士,我喜歡你的副臂。 –

回答

1

這很大程度上取決於您在桌上執行的查詢類型。如果您按照您的代碼示例指示的那樣對錶格進行規範化處理,則最終必須執行JOIN以及一些額外的處理來檢索給定比賽的數據。如果您的數據庫索引良好,這應該不會太慢,但這是一項額外的工作。但是,如果你確信任何一場比賽都會有五場,不多也不少,分場/分數,反規範化(Split1...Split5)會讓你的表現稍微好一點,但會是一場巨大的痛苦如果你曾經(說)添加第六次拆分。

您的電話;只有你可以知道什麼是最適合你的應用的。

+0

@ternus在我的例子中總是有5個分數和分割,但實際上可以有3個或4個分數或分割。第二個替代方案提供的性能提升是否歸因於記錄數量。 – Mutuelinvestor

+1

不,只是您不必執行SQL'JOIN'來檢索所有分割/分數。如果您知道總是**小於5,您可以創建5個字段並將其中的一些留空。但是如果有任何懷疑**,只需對數據進行標準化處理,以免技術債務未來之鬼在半夜訪問您。 –

+0

請參見[SQL Server Infernals - 第1部分 - 低級異常化程序](http://spaghettidba.com/2015/06/17/sql-server-infernals-row-1-undernormalizers/)並查看「正在執行的線索它錯了「 - 尤其是」具有數字後綴的列(例如Zone1,Zone2,Zone3 ...)「。嚴重:**不要這樣做!**不管你怎麼想 - 它***會在某天回來困擾你(或你的繼任者)。所以只是不要這樣做(並且絕對**不會將它推薦給其他人!) - 正確地標準化您的數據! –

3

你是對的 - 第一種方法更好。的第二種方法缺點:

  1. 困難,增加新的部分或分割(有時規則改變,或出現奇特的種族)
  2. 問題時,您需要選擇部分或拆分數據。您需要在5個分數和5個分列上創建索引。這會降低性能。
  3. 從這樣的表中選擇數據的代碼應該明確地處理這些額外的列。而不是使用循環,您需要硬編碼字段Fraction1,...,Fraction5和Split1,...,Split5。由於重複的代碼段可能會發生一些錯誤。

然而,第二種方法有更好的性能,但現代應用程序使用緩存「記住」非規格化數據。所以這個好處是微不足道的。