0

我正在创建一个抵押/贷款数据库 - 我有一个名为抵押贷款的表,其中包含以下字段:

  • 抵押id
  • client_id
  • *rate_type*(可能是:固定或跟踪器)...等

根据 rate_type 的选择 - 后面的字段会有所不同。例如,如果选择了固定利率类型的抵押贷款,那么用户将只输入该固定利率。如果是跟踪抵押贷款,则需要跟踪利率,例如 +0.90% 和基本利率(正在跟踪),例如 0.50% [给出调整后利率 = 1.40%]。

我的问题是:我该如何为此实施正确的表/字段结构。理想情况下,我不想拥有所有字段(突出显示):

  • 抵押id
  • client_id
  • rate_type
  • 固定利率
  • 跟踪速率
  • base_rate

因为它可能会导致混乱。有什么办法可以将这些分成其他表吗?也许另一个具有一对一关系的 rate_details 表(一个用于固定,另一个用于跟踪器)?

4

5 回答 5

1

根据您的问题,我建议您可以创建 3 个表。

1 用于基本信息,一个用于存储固定费率详细信息的表,以及一个用于存储基本费率详细信息的表。

tbl抵押贷款:

抵押ID | 客户编号 | 费率类型

tblFixedRates:

编号 | 抵押ID | 固定利率

tblTrackerRates:

编号 | 抵押ID | track_rate, base_rate

于 2011-11-02T20:48:04.977 回答
1

您所拥有的是一个 ER 模型,其类型(抵押)提供一组公共属性,每个属性都是 0 或 1 个子类型的实例,提供额外的特定于子类型的属性。请参阅我的答案

派生概念 - 数据库设计注意事项

我应该设计一个 SQL Server 数据库来依赖 UNION 还是避免它?

如何解决这个问题。

类型/子类型模型

于 2011-11-02T20:58:24.380 回答
0

正如其他人所建议的那样,我的建议是 FixedRateMortgages 和 TrackerRateMortgages 的 2 个子表,它们将 MortgageID 作为主键,并作为外键返回到主 Mortgages 表。

这确保了一对一,但它不会强制抵押只存在于两个子表之一中。这是数据库不能很好地执行的约束,这不是我们在这里讨论的引用完整性。您可以在子表上使用触发器来确保只插入其他子表中不存在的抵押贷款,但触发器非常难看恕我直言。我可能会坚持在您的应用程序层(即代码)而不是数据库中强制执行该不变量。

于 2011-11-02T21:05:39.290 回答
0

将所有三列都放在同一个表中是有效的,但只根据需要使用其中的 1 或 2 个。所有三列都可以为 NULLABLE。

另一种选择是为任一类型的费率类型使用 2 列,但在处理固定费率时将其中一列设置为 0。由于您要添加两个费率来得出总跟踪费率,因此固定费率加 0 的值将是固定费率。

[dbo].[theTable]
   [mortgage_id],
   [client_id],
   [rate_type],
   [base_rate],
   [rate]       // or whatever generic name is appropriate

所以当 [rate_type] 是跟踪你有

[base_rate] = 0.50%
[rate] = 0.90%

total = 1.40%

但是当 [rate_type] 固定时,你有

[base_rate] = 0%
[rate] = 0.70%

total = 0.70%
于 2011-11-02T20:56:08.707 回答
0

使用 SQL 约束可以达到的最佳效果FOREIGN KEY是确保每个抵押类型在每个子类型表中最多出现一次,如果愿意的话,是一对零或一关系。{ ID , type }强制执行此约束的一种方法是在整个架构中使用两列复合键,并允许type在子表约束中进行测试。这是使用两种抵押子类型的粗略草图(大括号表示没有隐含顺序的列表):

Mortgages { mortgage_ID , mortgage_type } 
   KEY { mortgage_ID } 
   KEY { mortgage_ID , mortgage_type }
   CONSTRAINT mortgage_type = 'Tracker'
              OR mortgage_type = 'Fixed'

FixedRateMortgages { mortgage_ID , mortgage_type , fixed_rate }
   KEY { mortgage_ID , mortgage_type }
   FOREIGN KEY { mortgage_ID , mortgage_type } REFERENCES Mortgages
   CONSTRAINT mortgage_type = 'Fixed';

FixedRateMortgages { mortgage_ID , mortgage_type , base_rate , track_rate }
   KEY { mortgage_ID , mortgage_type }
   FOREIGN KEY { mortgage_ID , mortgage_type } REFERENCES Mortgages
   CONSTRAINT mortgage_type = 'Tracker';

Clients { client_ID } 
   KEY { client_ID } ;

Agreements { mortgage_ID , mortgage_type , client_ID }
   KEY { mortgage_ID , mortgage_type , client_ID }
   FOREIGN KEY { mortgage_ID , mortgage_type } REFERENCES Mortgages
   FOREIGN KEY { client_ID } REFERENCES Client;

您没有指定 SQL 产品。可以在标准 SQL-92 中使用声明为封装每个子类型表逻辑的“分布式”的CREATE ASSERTION约束来维护严格的一对一引用完整性。DEFERRABLE INITIALLY DEFERRED然后,SQL 语句可以在事务中推迟ASSERTIONs,修改引用和引用的表,然后重新应用ASSERTIONs(或通过提交事务自动执行此操作)。遗憾的是,现实生活中没有支持CREATE ASSERTION. 有一些解决方法取决于供应商,例如触发器、从行级CHECK约束调用的 SQL 函数中的表表达式、撤销表的写权限然后强制用户通过确保引用完整性的 CRUD 过程更新表等。

也就是说,在 SQL 中,一对零或一关系通常是可以接受的,并且确实这样做可能有好处,例如使数据库约束更易于编写(因此错误更少),不强迫用户的灵活性使用一套程序等

于 2011-11-03T09:31:55.937 回答