2011-09-30 75 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年,请参阅我发送的链接顶部的“其他版本” –