blogger13 Asked: 2024-11-25 03:28:43 +0800 CST2024-11-25 03:28:43 +0800 CST 2024-11-25 03:28:43 +0800 CST 下表包含两个外键是否也是该表的主键? 772 具有两个外键的单个表是否也可以被视为该表的主键(合在一起)?我正在添加我正在阅读的《计算机科学邀请》第 6 版InsurancePolicies教科书中的屏幕截图,其中显示了具有两个外键的表,但我的问题是,这两个外键是否也被视为该表的主键?教科书中的作者没有明确说明这一点。 我认为答案是肯定的,但我不确定,而且我找不到具体的答案,所以希望有人能提供一个易于理解的答案。 这是我在这里能找到的最接近的答案,所以我的第二个问题是,默认情况下这两个外键是否也被视为主键? sql 3 个回答 Voted Best Answer keithwalsh 2024-11-25T04:21:17+08:002024-11-25T04:21:17+08:00 是的,一个表可以有 2 个或更多外键,它们共同形成一个复合主键。 复合键需要明确声明,即使它们由外键组成。 CREATE TABLE InsurancePolicies ( EmployeeID INTEGER, PlanType VARCHAR(50), DateIssue DATE, PRIMARY KEY (EmployeeID, PlanType), FOREIGN KEY (EmployeeID) REFERENCES Employees(ID), FOREIGN KEY (PlanType) REFERENCES InsurancePlans(PlanType) ); 如果没有明确声明,您将无法强制唯一性,并且可能允许重复的 (EmployeeID, PlanType) 对。 Guido 2024-11-25T03:42:26+08:002024-11-25T03:42:26+08:00 2 个 FK 键的组合就是所谓的“复合主键”,因此可以作为主键。SQL 表中的复合键是由两个或多个列组合而成的主键,用于唯一标识表中的记录。当单个列无法唯一标识一行,但列组合可以时,可以使用复合键。 Lajos Arpad 2024-11-25T04:16:14+08:002024-11-25T04:16:14+08:00 AKEY是具有特殊含义的 1 列或多列的组合。这种含义可以是索引(用于加速按所述列进行的搜索)、唯一键(确保表中不存在两个记录,这些记录的键值组合与作为键一部分的列相同)、外键(列的组合,它们共同表示对另一个表的主键的引用)和主键,它们也可以是复合键。 现在您了解任何键都是 (c1, c2, ..., cn) 的形式,其中 c1 ... cn 是列,这应该澄清主键以及其他键对组成它的列数没有限制。 现在,假设您有一个列 C,它在其所属的表中实际上是唯一的。除非指定,否则此字段不会成为键、非唯一键或主键,也不会成为任何其他东西,即使它可以是唯一键或主键。 一组唯一的列的组合就是候选键,可以用作主键。 InsurancePolicies您的表中EmployeeID有一个外键引用Employees,InsurancePlans并由名为的外键引用PlanType。 图中没有提到它们是(EmployeeID和PlanType)的主键,并且,除非深橙色表示主键(我并不相信),否则您没有理由认为它们是一起的主键。 甚至不能保证这种可能性。如果一名员工购买了一份保险计划并支付了几个月的费用,然后转到了另一份计划,但后来又转回了他原来的计划,该怎么办? 假设员工 1 于 2000 年 1 月 1 日为 InsurancePlan1 签发了保险,并一直在付款,直到 2010 年 1 月 1 日,员工 1 代替 InsurancePlan1 为 InsurancePlan2 签发了保险。然后,在 2020 年 1 月 1 日,员工 1 再次为 InsurancePlan1 签发了保险。 这意味着 Employee1 有两个不同DateIssued的 InsurancePlan1,在当前构造中只能用InsurancePolicies表中的两个不同的记录来表示,其EmployeeID和PlanType匹配,从而违背了将这两个字段一起用作主键的目的。 如果您的项目由于某种原因而无法实现这种情况,那么您将能够使用此组合作为主键,但即使这种情况现在不可能实现,但随着项目的发展,以后也可能会成为可能。 因此,正如 Boyce-Codd 在BCNF(Boyce-Codd 范式)中提出的那样,数据库规范化的进一步步骤是避免使用此类复合主键,即使它们是完全合法的,因为随着时间的推移,如果它们最终被证明是可重复的,您可能最终不得不重构大型数据库。相反,此范式建议在每个表中都有一个原子的 1 维键,因此您将有一个新的ID字段InsurancePolicies作为主键,从外键的角度来看,这将是一个万无一失的解决方案,因为,如果事实证明同一个员工出于某种原因可能不止一次拥有相同的保险计划(例如,两辆汽车投保了相同的计划),那么您的架构仍将实现目的。 至于(EmployeeID,PlanType)现在是否是主键,请检查表定义,查看表的具体定义方式以及这两个字段是否一起充当主键。
是的,一个表可以有 2 个或更多外键,它们共同形成一个复合主键。
复合键需要明确声明,即使它们由外键组成。
如果没有明确声明,您将无法强制唯一性,并且可能允许重复的 (EmployeeID, PlanType) 对。
2 个 FK 键的组合就是所谓的“复合主键”,因此可以作为主键。SQL 表中的复合键是由两个或多个列组合而成的主键,用于唯一标识表中的记录。当单个列无法唯一标识一行,但列组合可以时,可以使用复合键。
A
KEY
是具有特殊含义的 1 列或多列的组合。这种含义可以是索引(用于加速按所述列进行的搜索)、唯一键(确保表中不存在两个记录,这些记录的键值组合与作为键一部分的列相同)、外键(列的组合,它们共同表示对另一个表的主键的引用)和主键,它们也可以是复合键。现在您了解任何键都是 (c1, c2, ..., cn) 的形式,其中 c1 ... cn 是列,这应该澄清主键以及其他键对组成它的列数没有限制。
现在,假设您有一个列 C,它在其所属的表中实际上是唯一的。除非指定,否则此字段不会成为键、非唯一键或主键,也不会成为任何其他东西,即使它可以是唯一键或主键。
一组唯一的列的组合就是候选键,可以用作主键。
InsurancePolicies
您的表中EmployeeID
有一个外键引用Employees
,InsurancePlans
并由名为的外键引用PlanType
。图中没有提到它们是(
EmployeeID
和PlanType
)的主键,并且,除非深橙色表示主键(我并不相信),否则您没有理由认为它们是一起的主键。甚至不能保证这种可能性。如果一名员工购买了一份保险计划并支付了几个月的费用,然后转到了另一份计划,但后来又转回了他原来的计划,该怎么办?
假设员工 1 于 2000 年 1 月 1 日为 InsurancePlan1 签发了保险,并一直在付款,直到 2010 年 1 月 1 日,员工 1 代替 InsurancePlan1 为 InsurancePlan2 签发了保险。然后,在 2020 年 1 月 1 日,员工 1 再次为 InsurancePlan1 签发了保险。
这意味着 Employee1 有两个不同
DateIssued
的 InsurancePlan1,在当前构造中只能用InsurancePolicies
表中的两个不同的记录来表示,其EmployeeID
和PlanType
匹配,从而违背了将这两个字段一起用作主键的目的。如果您的项目由于某种原因而无法实现这种情况,那么您将能够使用此组合作为主键,但即使这种情况现在不可能实现,但随着项目的发展,以后也可能会成为可能。
因此,正如 Boyce-Codd 在BCNF(Boyce-Codd 范式)中提出的那样,数据库规范化的进一步步骤是避免使用此类复合主键,即使它们是完全合法的,因为随着时间的推移,如果它们最终被证明是可重复的,您可能最终不得不重构大型数据库。相反,此范式建议在每个表中都有一个原子的 1 维键,因此您将有一个新的
ID
字段InsurancePolicies
作为主键,从外键的角度来看,这将是一个万无一失的解决方案,因为,如果事实证明同一个员工出于某种原因可能不止一次拥有相同的保险计划(例如,两辆汽车投保了相同的计划),那么您的架构仍将实现目的。至于(
EmployeeID
,PlanType
)现在是否是主键,请检查表定义,查看表的具体定义方式以及这两个字段是否一起充当主键。