2011-09-30 45 views
2

我有一個表來維護特定的業務交易,我們稱之爲LOANS。每個記錄可以在任何給定時間具有幾個「狀態」中的一個,例如「在重新支付/開放」,「默認」,「無效」或「支付」中。如何表示當前狀態或狀態並保持數據/參照完整性? - 數據庫設計

記錄的狀態只能由於應用程序用戶採取的「事件」或行動而改變(某些事件不會導致狀態改變,例如付款會修改記錄但不會改變狀態) 。在跟蹤當前狀態的同時,我們還可以輕鬆跟蹤將事務置於此狀態的「事件」。

我看過其他數據庫的設置,使得LOANS包含一個狀態列,並且使用一個字母(或者甚至是一個可能狀態表的外鍵)來指定當前狀態。然後EVENTS表的列有一個FKLOANS

該解決方案有效,但我擔心這會導致數據完整性可能丟失。換句話說,沒有什麼可以阻止狀態被設置爲「默認」,沒有EVENT來支持這種改變。它將完全留給應用程序來確保永遠不會發生(在我看來,這個解決方案沒有參照完整性)。

我的替代解決方案是取消LOANS中的狀態列,而是使用lastEvent列,該列是FK到EVENTS。然後表格將保持事件的「類型」,這將反過來描述狀態變化(例如,如果lastEvent是「付款」類型,那麼自然狀態是「付費」)。

我的問題是:

  1. 應我甚是關心數據的完整性(這是這樣做的,因爲它是確定做一個平常的事)?
  2. 是我提出的解決方案,還是有更好的解決方案?
  3. 我應該知道我的解決方案中是否有任何缺陷?

在它的事項的情況下,我使用MS SQL Server 2005的

回答

1
  1. 只有你知道風險是什麼,如果你沒有參照完整性這裏 - 但在一般情況下,是的,這是值得設計數據庫,所以你可以使用參照完整性。它減少了錯誤,並增加了未來開發人員理解您的架構的可能性。

  2. 我會有一個模式,沿線...

    貸款


    Loan_Id(PK)

    量 ....

    活動


    EVENT_ID(PK)

    Loan_ID(FK)

    Event_type_id(FK)

    日期

    STATUS_ID(FK)

    EVENT_TYPE


    event_type_id(PK)

    描述

    狀態


    STATUS_ID(PK)

    描述

要找到任何負載的當前狀態,你需要找到的事件表,瞭解最新的項目貸款。要查看貸款狀態更改的歷史記錄,可以查詢事件表。

當你不改變的狀態記錄事件,新事件的記錄只包含事件的當前狀態 - 所以你可能會得到這樣一個表:

Event_id Loan_ID Event_type_id Date   status_id 
------------------------------------------------ 
1    1   NEW 1 Jan 2011 NEW 
2    1  APPROVE 2 Jan 2011 NEW 
3    1  DEFAULT 1 Feb 2011 DEF 
... 

這樣,你總是通過查找最新記錄來檢索當前狀態。

它大大降低了錯誤的風險 - 如果您的「事件」邏輯發生變化,並且事件確實會改變貸款狀態,您只需要在一個地方更改它 - 創建記錄的代碼事件數據庫。您不必記住也要更改「貸款」記錄。

至於性能 - 如果您真的需要,我只會對此進行優化 - 在一個調整良好的數據庫中,連接和max不應該是顯示停止符。

您可以通過創建映射有效狀態轉換及其相關事件的表格來優化模型;取決於你的數據庫,你可以通過觸發器強制執行。

我認爲這比「最後一個事件」外鍵更好,因爲它是多餘的 - 根據定義,最後一個事件是該貸款的MAX(日期)記錄。

+0

有些事件不會改變狀態,這是我選擇反觀剛看到最後一個事件的一個原因(但也許我可以推斷出不改變狀態的事件需要開始的初始狀態)。另一個原因是,我想可能在lastEvent中存儲它會比每次我想要某個特定狀態的所有項目(這種類型的調用將會發生很多)時調用MAX(日期)更快。 – LittleTreeX

+0

將更新答案以解決這些問題... –

0

我覺得你對誠信的疑慮是有效的。您已經指定了一個業務規則,實際上狀態不是可推斷的可寫屬性 - 來自事件。

根據您的活動數據,我會讓它成爲computable column

只能猜測你的數據庫實現,所以另一種選擇是觸發更新列,但你將如何確保其只讀? (推測可能與鎖/權限)

+0

爲了清楚起見,我使用的是SQL SERVER 2005。 – LittleTreeX

+0

計算列可在2005年,請參閱我發送的鏈接頂部的「其他版本」 –