2010-03-01 22 views
0

我有一個模型,它看起來是這樣的:在建模標題/細節關係時消除冗餘關係?

Model

一個帳戶擁有衆多分支機構,併爲一個賬戶中產生的每條語句。該模型是多餘的,因爲帳戶(標題上的AccountID)可以從事務的BranchID中推斷出來(一個語句總是會有一個或多個事務)。

應該從StatementHeader中刪除AccountID,還是這種冗餘級別好?還是有更好的解決方案?

+0

我會避免使用「ID」作爲每個表中主鍵的名稱;你最終會在你的模型中加載它們,並且永遠無法確定你所指的是哪一個。 如果您使用代理鍵,那麼我建議您在整個模型中使用相同的名稱。您已將AccountID作爲外鍵,因此對主鍵使用相同的名稱。 – Tony 2010-03-01 13:14:33

+0

命名約定由其他人設定,所以我不能真正改變它。我讚賞你的理由,但我也有同樣的擔憂。 – ilitirit 2010-03-01 14:15:43

+0

什麼是StatementHeader的實體?在現實世界中,具有相同的StatementHeaderID的語句是相互連接的,還是AccountID和StatementDate都是共享的?後者會使StatementHeader類似於帶有SatementHeaderID的日曆作爲僞裝日期... – wallenborn 2010-03-03 13:30:06

回答

0

如果你有StatementHeader,那麼它應該有AccountID來保持參照完整性。

但是,最好將StatementHeader完全移除並將StatementDate移動到Statement記錄中。這會使事情變得更清潔,並使模型更好地描述你想要的東西。

+0

雖然這只是將冗餘移動到記錄,因爲每條記錄都具有相同的聲明日期。 – ilitirit 2010-03-01 12:30:07

+0

它使每個聲明記錄自成一體,這是很好的。 並非所有冗餘都不好 - 在這種情況下,性能會更好,因爲您可以消除連接以獲取日期。 我明白,在聲明日期可能發生變化的情況下,有一個'StatementHeader'表允許操縱日期,但除非我是錯誤的聲明日期在這種情況下不會經常改變,所以它是可以接受的。 – 2010-03-01 13:09:24

0

作爲一個陳述是歷史性的,通常只讀,數據一些redundency是好的。我同意Richard Harrison的意見,並將[AccountID]和[StatementDate]都移至[Statement]表中;我的理由是你說一個賬戶有很多分支機構,所以你將爲一個賬戶生成一個聲明。

將所有這些數據存儲在同一個地方將減少連接和加快報告,我認爲這是數據庫的原因。

0

有時,(真實的或感知的)冗餘是業務規則的結果。在這種情況下,業務規則是:「發給賬戶的聲明應僅包含屬於該特定賬戶的分行的交易。」

要強制執行該規則,您可以嘗試創建一個數據庫模式,使其無法違反它,或者使用約束或觸發器顯式強制執行。而且這似乎更容易與StatementHeader.AccountID。在Oracle中,你可以寫這樣的事情:在StatementHeader

create or replace trigger statement_has_unique_account 
before insert or update on Statement 
referencing old as old new as new 
for each row 
declare 
    m integer; 
    n integer; 
begin 
    select b.AccountID 
    into m 
    from Branch b 
    where b.ID = new.BranchID; 

    select s.AccountID 
    into n 
    from StatementHeader s 
    where s.ID = new.StatementID; 

    if m <> n then 
    raise_application_error(-1000, 'No way!'); 
    end if; 
end; 

沒有帳戶ID,你必須寫與共享同一StatementID所有其他語句中的所有其他AccountIDs進行比較,從而產生更復雜報表序列。

所以我會將AccountID作爲一個外鍵在StatementHeader中,並用觸發器明確地強制執行業務規則。