【发布时间】:2013-01-31 04:18:31
【问题描述】:
我想知道为什么 Adventure 工作数据库中的 EmailAddress 表使用复合主键(BusinessEntityID,EmailAddressID(Identity))? 如果它与为这两个字段设置集群索引有关,如果告诉我复合主键如何物理存储(以何种顺序以及如何插入数据),我将不胜感激?
【问题讨论】:
标签: sql sql-server sql-server-2008 tsql
我想知道为什么 Adventure 工作数据库中的 EmailAddress 表使用复合主键(BusinessEntityID,EmailAddressID(Identity))? 如果它与为这两个字段设置集群索引有关,如果告诉我复合主键如何物理存储(以何种顺序以及如何插入数据),我将不胜感激?
【问题讨论】:
标签: sql sql-server sql-server-2008 tsql
因为这样,同一个e-mail地址可以被多个Person使用,并且同一个Person可以使用多个e-mail地址,也就是说,它使得person和e-mail地址之间的关系多-对多。
如果只需要强制电子邮件地址应属于某个人,则将其设为外键并且BusinessEntityID 列不可为空就足够了。
更新:
这里涉及到 2 个表,Person 和 EmailAddress。
Person 中的每条记录都由 BusinessEntityID 标识。要将来自Person 的记录与另一个表T 中的记录相关联,只需在此表T 中包含一个引用BusinessEntityID 的列就足够了。现在,如果我们需要确保T 中的所有记录必须与Person 中的某些记录相关联,那么我们将在T.BusinessEntityID 上放置外键约束并使其不可为空。如果除此之外,我们希望确保T 中的每条记录必须与Person 中的一条且只有一条记录相关联,那么我们可以对列T.BusinessEntityID 设置唯一性约束。
当我们将两列 A 和 B 作为表的主键的一部分时,我们告诉数据库这两列的值一起必须对所有人都是唯一的该表中的记录。它与每个列中的值和任何外键关系无关。
举例说明:
Person (BusinessEntityID, Name) and PK is BusinessEntityID
---------------
1 | John
---------------
2 | Jane
---------------
3 | Sales Team
EmailAddress (BusinessEntityID, EmailAddressID, EmailAddress) and PK is [Business EntityID, EmailAddressID] where EmailAddress is auto-incremented
--------------
1 | 1 | john@example.com
------------------------
1 | 2 | john@contoso.com
------------------------
2 | 3 | jane@example.com
------------------------
2 | 4 | jane@contoso.com
------------------------
1 | 5 | sales@example.com
------------------------
2 | 6 | sales@example.com
------------------------
3 | 7 | sales@example.com
可以将与上述类似的数据放入示例中的表格中。现在这里发生了什么?
有 3 个实体,John、Jane 和销售团队。
John 有 2 个个人电子邮件地址。 Jane 也有 2 个个人电子邮件地址。此外,电子邮件address sales@example.com 属于销售团队,也属于 John 和 Jane。
这是一个多对多的关系。
此外,如果 EmailAddress 中的复合键是集群的,则键将按照它们出现的顺序存储。阅读this了解更多信息。
【讨论】:
EmailAddress 表的PK 的充分理由。通常,如果您有两个表A 和A.Id 和B 和B.Id,并且您希望A 和B 之间存在多对多关系,那么您可以创建第三个表C C.AId 和 C.BId,您可以制作 (AId, BId) the PK for C` 并为 AId 和 BId 设置 FK 以强制参照完整性。这显然不是这里发生的事情。我很抱歉在我的回答中误导了你。
那是因为组合,一个电子邮件地址不能没有一个人存在。 所以 BusinessEntityID 也是 EmailAddress 表的主键
【讨论】: