2009-10-15 19 views
8

我已經開始一個新項目,他們有一個非常規範化的數據庫。所有可以作爲查找的內容都將作爲查找表的外鍵存儲。這是正常化和罰款,但我最終爲最簡單的查詢做了5個表連接。非正常化的理智或表現?

from va in VehicleActions 
    join vat in VehicleActionTypes on va.VehicleActionTypeId equals vat.VehicleActionTypeId 
    join ai in ActivityInvolvements on va.VehicleActionId equals ai.VehicleActionId 
    join a in Agencies on va.AgencyId equals a.AgencyId 
    join vd in VehicleDescriptions on ai.VehicleDescriptionId equals vd.VehicleDescriptionId 
    join s in States on vd.LicensePlateStateId equals s.StateId 
    where va.CreatedDate > DateTime.Now.AddHours(-DateTime.Now.Hour) 
    select new {va.VehicleActionId,a.AgencyCode,vat.Description,vat.Code, 
vd.LicensePlateNumber,LPNState = s.Code,va.LatestDateTime,va.CreatedDate} 

我想推薦我們確定一些東西。像州代碼一樣。我沒有看到我的有生之年改變了州代碼。與三字母機構代碼類似的故事。這些是由代理機構發放的,不會改變。

當我與國家代碼問題和5表連接的DBA接近。我得到了「我們正常化」和「加入速度很快」的迴應。

是否有一個引人注目的非規範化論據?如果沒有其他的事情,我會爲了理智而去做。

在T-SQL相同的查詢:

SELECT VehicleAction.VehicleActionID 
     , Agency.AgencyCode AS ActionAgency 
     , VehicleActionType.Description 
     , VehicleDescription.LicensePlateNumber 
     , State.Code AS LPNState 
     , VehicleAction.LatestDateTime AS ActionLatestDateTime 
     , VehicleAction.CreatedDate 
FROM VehicleAction INNER JOIN 
    VehicleActionType ON VehicleAction.VehicleActionTypeId = VehicleActionType.VehicleActionTypeId INNER JOIN 
    ActivityInvolvement ON VehicleAction.VehicleActionId = ActivityInvolvement.VehicleActionId INNER JOIN 
    Agency ON VehicleAction.AgencyId = Agency.AgencyId INNER JOIN 
    VehicleDescription ON ActivityInvolvement.VehicleDescriptionId = VehicleDescription.VehicleDescriptionId INNER JOIN 
    State ON VehicleDescription.LicensePlateStateId = State.StateId 
Where VehicleAction.CreatedDate >= floor(cast(getdate() as float)) 
+0

+1。好問題。 – David 2009-10-15 21:49:36

回答

6

我不知道我是否會打電話給你想做非規範化 - 它看起來更像是你只是用自然的外鍵(州縮寫,代理代碼)替換人工外鍵(StateId,AgencyId) 。使用varchar字段而不是整數字段會降低聯接/查詢性能,但(a)如果你甚至不需要大部分時間加入表,因爲自然FK是你想要的,這不是什麼大問題, b)你的數據庫需要非常大/有很高的負載才能顯着。

但djna是正確的,因爲您需要在完成像這樣的改變之前完全理解當前和未來的需求。你是否確信三個字母的代碼將永遠不會改變,即使是五年後?真的,真的嗎?

+1

我曾經是自然外鍵的優雅,邏輯和清晰度的巨大粉絲,但他們只是不值得經常維護的麻煩。因此,我創造了優雅的工具來管理人造鑰匙,並在每個人的家中及時享用晚餐。 – overslacked 2009-10-16 01:30:41

3

這個之前的帖子查處了類似的問題,你遇到的一個。希望這會對你有所幫助。

Dealing with "hypernormalized" data

我個人採取的正常化正常化儘可能,但非規範化只爲性能。而且,爲了避免表現出的非規範化是需要避免的。在我進行非規範化之前,我會走分析的路線,設置正確的索引等。

理智......這是高估。特別是在我們的職業。

+0

+1爲「理智」soundbite。請介意我偶爾引用你? ;-) – sleske 2009-10-15 22:00:09

+0

沒有。報價。 – David 2009-10-15 22:01:38

6

在某些時候,性能(和健康)原因可能需要一些非規範化。很難說沒有看到你所有的桌子/需求等......

但是,爲什麼不只是建立一些便利的意見(做一些連接),然後使用這些能夠編寫更簡單的查詢?

+1

+1爲觀點的想法...有用的,簡單的建議。 – David 2009-10-15 21:47:50

+0

小的,簡單的,可重複使用的函數應該適用於所有我們正確的代碼,如果可能的話。我從表值函數和視圖中獲得了很多里程。作爲獎勵,報告也變得更容易。 – overslacked 2009-10-16 01:26:53

6

謹防想要將事物塑造成您當前的成語。現在,不熟悉的代碼似乎對你的理解沒有影響。及時有可能你會適應。

如果當前(或未來已知的)需求(如性能未達到)那麼這是一個完全不同的問題。但要記住,任何事情都可以調整性能,目標不是儘可能快地做出事情,而是讓它們足夠快。

+1

+1指出開發人員往往隨着時間的推移而增長。我認爲在這種情況下,最好學會處理超標準化的數據,並調整而不是調整數據以適應我們的需求。 – David 2009-10-15 21:49:04

2

三個字母的代碼可能會改變的一個論點(對於這種「規範化」)沒有一個計劃,如果代碼確實會改變,你會做什麼,以及你的人造密鑰場景如何解決這個問題可能性比使用密碼作爲密鑰更好。除非你已經實現了一個完全時態的模式(這是非常難以完成的,並且沒有被你的例子所建議),但是我不清楚你的規範化對你有什麼好處。現在,如果您與來自多個來源和標準的代理商合作,這些代理商可能會碰撞代碼名稱,或者「州」最終可能意味着州,省,部門,州或州的兩字母代碼,那就是另一回事。然後,您需要自己的密鑰,或者需要一個包含比該代碼更多信息的雙列密鑰。

3

那麼,性能呢?如果性能沒有問題,只需將五個表JOIN放入一個視圖中,並且爲了理智,在需要數據時從視圖中選擇SELECT。

州的縮寫是我認爲有意義的鍵是好的情況之一。對於具有有限行數的非常簡單的查找表,以及我完全控制數據的位置(這意味着它不是從外部來源填充的),我有時會創建有意義的四個或五個字符的鍵,以便鍵值可以代理用於某些查詢中的完全描述性查找值。

3

創建視圖(或內聯表值函數以獲取參數化)。在任何情況下,我通常會將所有代碼放入SP(生成一些代碼),無論它們是否使用視圖,這就是你幾乎只寫過一次連接。