Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 具有更改内容的表的最佳主键_Sql_Sql Server_Database_Database Design - Fatal编程技术网

Sql 具有更改内容的表的最佳主键

Sql 具有更改内容的表的最佳主键,sql,sql-server,database,database-design,Sql,Sql Server,Database,Database Design,我在SQL Server中有一个“贷款明细”表 与订单/订单明细场景非常相似,明细表与父“贷款”表有关系,并且需要它自己的唯一主键,因为它在每个LoanId中包含多行 但是,由于它是财务数据,因此可以定期更改—每季度/6个月/每年,而不是每天或每小时 我正在尝试为贷款明细表建立主键。 每笔贷款可能有几种贷款利率,因此我目前有两种选择: PK1 在这种情况下,年率将用作主键的一部分(因为它对于贷款是唯一的) AnnualRate列未与任何其他表连接,但它会不时更改 PK2 在这种情况下,如果利率发

我在SQL Server中有一个“贷款明细”表

与订单/订单明细场景非常相似,明细表与父“贷款”表有关系,并且需要它自己的唯一主键,因为它在每个
LoanId
中包含多行

但是,由于它是财务数据,因此可以定期更改—每季度/6个月/每年,而不是每天或每小时

我正在尝试为贷款明细表建立主键。

每笔贷款可能有几种贷款利率,因此我目前有两种选择:

PK1

在这种情况下,年率将用作主键的一部分(因为它对于贷款是唯一的)

AnnualRate
列未与任何其他表连接,但它会不时更改

PK2

在这种情况下,如果利率发生变化,主键不会改变,但贷款人仍可添加或删除利率。简言之,主键的变化频率必须降低


作为一个缺乏SQL经验的人,我正在寻求建议,因为在这一点上的任何错误都可能很难进一步纠正。

在我看来,主键应该是
LoanId
DateRateSet
,这将是一个时间戳,当
LoanId
的速率发生变化时,它会发出信号。这就是梳子取消年利率将使
年利率
唯一标识

例如:

LoanId  DateRateSet          AnnualRate
1       2017-01-01 01:04:20  0.05
1       2017-02-01 01:20:20  0.03
1       2017-08-01 05:04:20  0.05
1       2017-09-01 01:20:24  0.02

它们可以在同一个
LoanId
中重复,但是您可以为每一个都指定一个时间戳。

您应该有一个唯一的标识列作为主键。我希望这样做:

create table LoanDetail (
    LoanDetailId int identity(1, 1) primary key,
    LoanId int references Loans(LoanId),
    Rate decimal(9, 4),
    eff_date date not null,
    end_date date
);

eff_date
end_date
表示速率有效的时间段。

这里真正的问题是主键、自然键和代理键之间的区别

自然键是数据中存在的一列或一组列,使数据行唯一。自然键可能存在,也可能不存在

代理项键是添加到数据中以使数据行唯一的一列或一组列。您没有“找到”代理项键,而是创建了它

主键唯一标识一行数据。它可以是自然键,也可以是代理键,但在任何一种情况下都是不可变的。否则,您将失去引用完整性


从loan details表中的内容来看,当前唯一不可变的列是LoanId。这很好,但这意味着如果表中要有主键,它必须是代理键,Gordon在他的回答中列出了用于设置它的DDL。

只需使用定义为IDENTI的LoanDetailID列即可TY。没有人能真正聪明地回答你的问题。要做到这一点,需要了解你的实体实际建模的内容。通常(IME)贷款的利率不会随时间而变化,因此你的模型是不寻常的。此外,你选择的名称(详细信息)不会添加任何内容来帮助理解其用途。可能会出现一个标识列“足够好了”,但您应该适当地约束自然键。不幸的是,这需要更好地理解。但是
结束日期可以由下一个速率的
生效日期
确定,无需添加列。@intael…如果两个日期都在每一行中,则该表更易于使用。”自然键是数据中存在的一组列…自然键可能存在,也可能不存在。“--在上下文中,这对我来说没有意义。我有两笔贷款,都在同一家机构,它们被批准的年份唯一地标识了它们。发行人批准了数千笔贷款,并分配了一个帐号来唯一地标识每一笔贷款;我们称之为可信来源。一个具有良好属性的自然密钥(小型、稳定、可验证、用户熟悉、由可信来源维护等)可能存在,但可能不存在于您的数据中,例如,因为您没有进行研究!…在OP的示例中,他们似乎需要一个时间键,即负载的唯一标识符和利率(或其他)的时间间隔之间的复合键适用于未平仓区间进一步确定当前利率的情况。
AnnualRate decimal(9,4)
... etc.
LoanId  DateRateSet          AnnualRate
1       2017-01-01 01:04:20  0.05
1       2017-02-01 01:20:20  0.03
1       2017-08-01 05:04:20  0.05
1       2017-09-01 01:20:24  0.02
create table LoanDetail (
    LoanDetailId int identity(1, 1) primary key,
    LoanId int references Loans(LoanId),
    Rate decimal(9, 4),
    eff_date date not null,
    end_date date
);