0

可以将复合键设置为另一个表的主键吗?

例如我有表格:

  • Books - 带主键:Product_ID
  • Client- 带主键:Client_ID
  • Clients_Books- 使用复合主键:Product_IdClient_ID

我想将此复合主键从 Clients_Books 设置为另一个名为 Order_Details 的表的主键。但我不想使用 Books、Clients 表中的 Product_ID 和 Client_ID。

这有意义吗?欢迎所有意见。

4

2 回答 2

1

你正走在一条黑暗而肮脏的道路上。不要这样做。坚持最佳实践——在表上使用简单的主键,然后在必要时对其他表使用外键。

于 2010-02-22T21:12:18.373 回答
1

简短的回答是,不——不能那样做。PK(或其他备用键)中的所有列都必须出现在 FK 定义中。还要记住,一个表可以有多个键 - 称为候选键(有时是备用键)。主键只是您设计/使用的“最佳”键(通常是最窄的键 - 字节大小最小)。我们将这些其他唯一索引的名称前缀为“AK_{name}” - AK = Alternate Key。

在这种情况下,我们做的是以下两件事之一:

  1. 将合成的 PK 定义为“身份”列,然后将唯一索引添加到复合键 - 因此表上有两个“键”。然后所有子表将 FK 定义为指向合成 Identity PK 列。
  2. 保持复合键不变。将其定义为该主表上的 PK,并使所有 FK 具有相同的定义。

通常,让多个表具有相同的 PK 定义(即,PK 也是另一个表的 FK)并不是一个好主意。我说“一般”——理解实体的定义很重要。

那么为什么要使用#1?我问自己的问题是复合键是否真的是定义行的数据?那个复合键真的是一行的定义,还是它更像是一些其他数据的 FK?如果它更像是一个 FK,那么我创建合成的 PK(Identity)。订单真的是客户拥有的书籍吗?一个订单可能会导致客户拥有一本新书——但它们可能不是一回事。

拥有合成 PK 在未来几年提供了更多选择。如果您的 Client_Books 表中的关系需要更改,那么您可以隔离对其他表的更改。

例如——如果客户可以拥有不止一本书籍怎么办——你将如何实现它?使用合成键,您可以简单地删除复合键上的唯一索引并将其保留为简单的 FK,然后 Order_Details 表将简单地表示客户何时购买了他们的第二个副本。但是,如果您在 Orders 路由上使用了复合键,那么您必须弄清楚如何重新定义 Order_Detail 以及 Client_Books(以及指向 Order_Detail 的任何其他 FK)。

我还要请您评估 Order_Detail 是否真的是 Client_Book?通常,订单会导致客户拥有一本新书。我认为订单独立于库存 - 因此 Order_Detail 上的 PK 不应该是 Client_Books 上的 PK,Order_Detail 可能应该有它自己的独立 PK。

于 2010-05-24T16:36:11.400 回答