【问题标题】:Storing all loan (insert loan date, update return date) records in one table or 2 tables (with history) is better?将所有贷款(插入贷款日期,更新归还日期)记录存储在一张表或两张表(有历史记录)中更好?
【发布时间】:2013-08-01 14:54:38
【问题描述】:

一个简单的数据库设计问题困扰了我一段时间,想在这里问一下。

假设我有一个数据库表"Loan",其中包含以下字段,

StudentIdentification, LoanDate, ReturnDate

该表用于跟踪每个借过东西的学生(不在数据库中)。 由于每个学生都可以贷还贷再贷(但不能多次贷不还,贷后必还),所以复合主键是

used: StudentIdentifcation and LoanDate

以这种方式存储数据还是使用 2 个表更好,

table 1: Loan   ( StudentIdentification, LoanDate)
table 2: LoanHistory   ( StudentIdentification, LoanDate, ReturnDate)

在这种情况下,贷款表的主键是

StudentIdentification

LoanHistory 表的主键是

StudentIdentification, LoanDate

每次学生返回时,“Loan”中的记录都会移动到“LoanHistory”表中,并更新 ReturnDate(在事务中完成)。

哪个更好?

【问题讨论】:

  • 哈哈,一个编程白痴可以访问SO,这就是区别
  • 真的,我的评论被删除了?!版主是否没有注意到 OP 的用户名实际上是“编程白痴”?伙计,这些天这里的每个人都很敏感。

标签: sql sql-server database oracle


【解决方案1】:

我会创建一个表,然后使用过滤索引 (SQL Server 2008+) 或索引视图 (SQL Server 2005-) 来强制每个学生只有一行,返回日期为 NULL :

CREATE TABLE Loans (
    StudentID int not null,
    LoanDate datetime not null,
    ReturnDate datetime null,
    constraint PK_Loans PRIMARY KEY (StudentID,LoanDate),
    constraint CK_Loans_NoTimeTravel CHECK (LoanDate < ReturnDate)
)

过滤后的索引:

CREATE UNIQUE INDEX IX_Loans_SingleOpen ON Loans (StudentID) WHERE ReturnDate IS NULL

索引视图:

CREATE VIEW dbo.Loans_SingleOpen_DRI
WITH SCHEMABINDING
AS
    SELECT StudentID FROM dbo.Loans WHERE ReturnDate IS NULL
GO
CREATE UNIQUE CLUSTERED INDEX IX_Loans_SingleOpen ON Loans_SingleOpen_DRI (StudentID)

(假设 dbo 是适当的架构 - SCHEMABINDING 需要它,而创建索引又需要它)

【讨论】:

    【解决方案2】:

    您可以使用简单的 SCD(缓慢变化维度)结构,并使用一张表来存储当前和历史数据。

    StudentIdentification, CreationDate, LoanDate, ReturnDate
    

    前两列是PK。

    您还可以添加金额来表示贷款或回报。

    你可能会发现this questionrelvant

    【讨论】:

      【解决方案3】:

      创建一个包含三列的表是最简单的方法。它允许您回答诸如“2013 年 3 月有多少学生借了东西?”之类的问题。容易地。如果您有两个表,则需要访问这两个表才能回答该问题,因为您实际上有一个“未结贷款”和“已归还贷款”表。

      可能是您的系统对当前开放的贷款非常感兴趣。它们可能会经常被查询和更新。在这种情况下,如果您将当前活跃的贷款放在一个表中,并且将历史记录推到辅助表中,它会表现得更好。如果您需要保留大量历史但您很少阅读,这很好。

      【讨论】:

      • 是的,你是对的。除非那张桌子上有很多杂物,否则最好在一张桌子上处理所有东西。好建议
      【解决方案4】:

      要提供准确的答案,请提供更多信息。关于应用程序是需要的。例如,为什么不拥有一个具有 StudentId 和 LoanDate 的表,主键为 StudentId。当归还借出的项目时,删除该行。因此,没有 StudentId 记录,那么当前没有任何内容被借出。此建议假定 LoanDate 对于发送迟到的提醒很重要。如果不需要延迟提醒,那么为什么还要设置 LoanDate?

      如果您需要贷款历史,包括归还日期和贷款日期。然后添加第二个历史表来存储行,因为它们从贷款表中删除,并带有额外的返回日期字段。

      【讨论】:

        猜你喜欢
        • 2014-07-23
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多