【问题标题】:How do primary keys work in junction tables for a DBMS? How can a composite key be a primary key?主键如何在 DBMS 的联结表中工作?复合键如何成为主键?
【发布时间】:2020-04-04 17:33:04
【问题描述】:

在 DBMS 中我们有

  1. Superkey - 一个属性或一组属性,用于唯一标识表中的一行。
  2. 候选键 - 唯一标识表中行的属性或属性集。超级密钥和候选密钥之间的区别在于,候选密钥的任何子集都不能作为候选密钥。
  3. 主键 - 选定的候选键,成为唯一标识行的属性。

如果我们想识别两个表之间的多对多关系,我们可以定义一个联结表,例如:

表格:

Author(AuthorID, FirstName, LastName) -- AuthorID is primary key
Book(BookID, BookTitle) -- BookID is primary key

创建两者之间的关系:

AuthorBook(authorID, BookID) -- together authorID and BookID are primary key

我认为 bookID 和 authorID 都是各自的主键。

既然候选键(因此是主键)不能有包含候选键的子集,那么 authorID 加上 BookID 怎么能是主键呢?这似乎打破了主键的定义。

我知道这可能是现实世界和理论之间的区别,但是由于我读过的 DBMS 教科书似乎以这种方式定义联结表并以这种方式定义主键,因此那里似乎存在脱节。

我误解了这个概念吗?

【问题讨论】:

  • 是的,你误会了。一个表可能有几个候选键——这就是它们是“候选”的原因。 (如您所说,每个属性都可能包含多个属性。)主键是候选者之一,通常出于某些实用/人体工程学的原因而选择为主键。您的联结表是所有关键(就像联结表通常一样),所以只有一个候选者,所以它必须是主要的。
  • 请查看我如何将“both”替换为“together”和“and”替换为“plus”,以便清楚并与“composite PK”保持一致。使用“both”和“and”并不清楚您是在谈论 2 个属性,每个属性都是一个 PK 与 2 个属性形成一个 PK。
  • 您的参考资料是什么?遵循(好的)出版的关于信息建模、关系模型和数据库设计和查询的学术教科书。 (记录和使用设计的语言和工具手册不是这样的教科书。)(维基文章或网络帖子也不是。)数十种已出版的学术信息建模和数据库设计教科书以 pdf 格式在线免费提供。

标签: database relational-database primary-key rdbms candidate-key


【解决方案1】:

当我们使用其中一个术语时,我们必须谈论给定的表(变量、值或表达式)。一个表的超级键、CKs 和 PKs 不是由它的属性在其他表中扮演的角色决定的。它们取决于在给定的业务规则下,表可能出现的有效值。

Superkey - 一个属性或一组属性,用于唯一标识数据库中的一行。

给定表的超键可以定义为一组“唯一标识行”的属性。(不是数据库。)虽然引用的短语是一种简写,如果您还不知道它的含义,这不是一个非常清晰的描述。

给定表的超键可以定义为一组属性,其子行值只能在表中出现一次。或者作为一组属性,在功能上确定表中的每组属性。

当一个超级键只有一个属性时,我们可以草率地谈论该属性是一个超级键。

候选键 - 一个属性或一组属性,用于唯一标识数据库中的一行。

确实,某个表的每个 CK(候选键)都是该表的超键。但是您的意思是,当/当且仅当某些其他条件成立时,根据定义,一组属性是超级键。但是你写这部分的时候并没有说清楚。

超级键和候选键的区别在于,候选键的任何子集都不能成为候选键。

没有。一个集合是它自己的一个子集,所以一个 CK 是它自己的一个子集,所以一个 CK 总是有一个子集是一个 CK——它自己。你的意思是,没有适当的/更小的子集。那么你的说法是正确的。但同样真实且更重要的是,CK 的任何适当/较小的子集都不是超级密钥。

您实际上并没有在本段中定义“CK”。 可以将给定表的 CK 定义为该表的超键,其中不包含作为该表超键的适当/较小子集。

主键 - 一个选定的候选键,成为唯一标识行的属性。

没有。 给定表的 PK(主键)定义为您决定调用 PK 的该表的一个 CK。(不是属性。)

请注意,CK 和 PK 是超级键。 PK 与关系理论无关。

创建两者之间的关系:

AuthorBook(authorID, BookID) -- together authorID and BookID are primary key

superkeys & CKs 是什么&所以 PK 可以是什么由表中的 FDs(功能依赖)决定。但是如果你假设这是一个多对多表,那么它需要一个 authorID-bookID 对来唯一标识一行,所以只能有一个 CK,{authorID,bookID}。所以这是唯一可能的PK。所以 {authorID} 和 {bookID} 不能是超级键或 CK 或 PK。

您可以通过查看示例和应用定义来了解这一点。

authorID bookID
      1      a
      1      b

这里的 authorID 不唯一标识一行。所以它不能是超级键。所以不可能是CK。所以不能PK。

我读过的教科书似乎以这种方式定义连接表并以这种方式定义主键

不,他们没有。

但是,他们确实说,联结表中的某些属性集和超键、CK 和 PK 子集是联结表中的 FK(外键),引用了它们是/的 CK(可能是 PK)的其他表在其他表格中。

给定表的 FK 可以定义为表中的一组特定属性,其子行值必须显示为某个其他表中的某些 CK 子行。

但是既然你说这是一个联结表,大概 {authorID} 是一个作者表的 FK,它的值出现在 CK/PK 下,而 {bookID} 是一个书表的 FK,它的值出现在一个CK/PK。因此,AuthorBook 中的 FK {authorID} 引用了 Author 中的 {authorID},而 AuthorBook 中的 FK {bookID} 引用了 Book 中的 {bookID}。

PS PK & other terms mean something else in SQL. 声明的 SQL PK 可以在其中声明一个较小的 SQL UNIQUE。 SQL“唯一性”本身是根据 SQL NULL 定义的。可以合理地说,SQL PK 更像是关系超级键,而不是关系 PK。同样,SQL FK 更容易让人联想到我们可以合理地称之为关系外键而不是关系外键。

【讨论】:

  • 感谢您的回答。我认为您所说的是因为在我的假联结表中 authorID 或 bookID 可以唯一标识一行。因为它是多对多的,一个 authorID 可以有多个 bookID,就像一个 bookID 可以有多个 authorID。所以只有结合起来才能发挥独特的作用。 (我的意思是表而不是上面的数据库)
  • 是的,我是这么说的。当您提出问题时,您似乎认为 {authorID} 和 {bookID} 中的每一个都是联结表 CK——“因为候选键(以及主键)不能有包含候选键的子集”。但是你的问题并没有说明你为什么这么认为——它并没有清楚地给出你所有的推理。您是否认为每个连接表行都是唯一标识的? (为什么?)或者你是否认为作为(分别)作者和书中的 CK/PK 意味着它们是其他表中的 CK/PK? (为什么?)
  • 我在想如果 bookID 和 authorID 本身都是主键,如果主键的要求之一是任何主键都不能有任何主键,那么它们如何结合起来成为主键,较小的子集,它本身就是一个键。但由于这是一个新表,我们不能将 authorID 和 bookID 视为自己的键。至少我认为是这样的。
  • 我将您评论中的新内容编辑到您的帖子中。 (请通过编辑而不是 cmets 进行澄清。)我希望从我的回答中可以清楚地看出你出错的地方是,当我们谈论一个表的键时,它必须是相对于给定表的。--“什么一个表的超级键、CKs 和 PK 不是由它的属性在其他表中扮演的角色决定的。”
猜你喜欢
  • 2018-08-26
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 2016-08-21
相关资源
最近更新 更多