如章引言所述,关系型数据库中的数据通常分布在多张表中,以保持结构清晰并减少冗余。设想一下,如果试图将顾客的全部信息以及他们所有的订单都存储在一张庞大的表中。这会很快变得难以管理且重复繁琐。相对而言,我们通常会有独立的表,例如一张用于顾客详情,另一张用于订单信息。但这些独立的表之间如何关联呢?数据库如何判断哪笔订单属于哪位顾客?这正是主键和外键的作用所在。它们充当连接器,用于建立和维护关联表之间的联系。主键:唯一标识符设想一张表是记录的集合,如同一个在线商店的全部顾客列表。Customers表中的每一行都代表一位独特的顾客。为了可靠地区分不同顾客,即使他们碰巧同名,我们也需要为每行设置一个唯一标识。这个唯一标识即是主键。主键是表中唯一标识每一行的一个列(或有时是多个列的组合)。主键列的主要特点:唯一性: 主键列中的每个值必须唯一。任何两行不能拥有相同的主键值。非空性: 主键列通常不能包含NULL值。每行都必须拥有一个有效的标识。考虑一个简单的Customers表:顾客ID名姓电子邮件101AliceSmithalice.s@example.com102BobJohnsonb.johnson@example.com103CharlieDavischarlie.d@example.com104AliceBrownalice.b@example.com在此表中,customer_id作为主键。每位顾客都拥有一个独特的customer_id(101, 102, 103, 104),这确保我们能够准确定位任何特定的顾客记录。即使有两位顾客名为“Alice”,他们独特的customer_id值(101和104)也使我们能够区分他们。电话号码或电子邮件地址可能看似唯一,但它们可能发生变化或并非适用于所有顾客,因此像customer_id这样专用的ID列是主键的更可靠选择。外键:连接表现在,我们引入一个Orders表来存储顾客购买信息:订单ID订单日期顾客ID总金额50012023-10-2610145.5050022023-10-26103120.0050032023-10-2710115.7550042023-10-2810488.20Orders表也有其自己的主键order_id,以唯一标识每笔订单。但请注意customer_id列。我们如何知道哪位顾客下了订单5001?我们查看该行中的customer_id值(101),并在Customers表中找到匹配的customer_id(101)。这告诉我们订单是由Alice Smith下的。Orders表中的customer_id列是外键。外键是某个表中的一个列(或多个列的组合),其值对应于另一个表中的主键值。它充当交叉引用,将包含外键的表(本例中为Orders表)中的行链接到包含相应主键的表(Customers表)中的行。主键告诉我们“这是此表中此行的唯一ID。”外键告诉我们“此值将此行与另一个表中的特定行关联起来。”强制关系:参照完整性外键不仅仅是标签;数据库系统常使用它们来强制执行参照完整性。这表示数据库确保表之间的关系保持一致。例如,在Orders和Customers表之间,customer_id列上正确定义外键关系后:你通常不能向Orders表插入一个customer_id在Customers表中不存在的订单。这可避免出现属于不存在顾客的“孤立”订单。根据数据库设置,规则可能会阻止你从Customers表删除一个在Orders表中仍有关联订单的顾客,或者它可能会自动处理这些关联订单(例如,通过一并删除它们或在允许的情况下将其customer_id设为NULL)。这些约束有助于维护关联表中数据的逻辑一致性。digraph G { rankdir=LR; node [shape=plaintext, fontname="Arial"]; edge [arrowhead=crow, arrowtail=none, dir=both, fontname="Arial", fontsize=10]; Customers [label=< <table border="0" cellborder="1" cellspacing="0"> <tr><td bgcolor="#4263eb" colspan="2"><font color="#ffffff"><b>顾客</b></font></td></tr> <tr><td port="pk" bgcolor="#a5d8ff"><u>顾客ID</u> (PK)</td><td>INTEGER</td></tr> <tr><td>名</td><td>VARCHAR</td></tr> <tr><td>姓</td><td>VARCHAR</td></tr> <tr><td>电子邮件</td><td>VARCHAR</td></tr> </table> >]; Orders [label=< <table border="0" cellborder="1" cellspacing="0"> <tr><td bgcolor="#1098ad" colspan="2"><font color="#ffffff"><b>订单</b></font></td></tr> <tr><td bgcolor="#99e9f2"><u>订单ID</u> (PK)</td><td>INTEGER</td></tr> <tr><td>订单日期</td><td>DATE</td></tr> <tr><td port="fk" bgcolor="#dee2e6">顾客ID (FK)</td><td>INTEGER</td></tr> <tr><td>总金额</td><td>DECIMAL</td></tr> </table> >]; Orders:fk -> Customers:pk [label=" 引用"]; }此图表显示了Customers和Orders表之间的关系。Customers表中的customer_id(PK - 主键)被Orders表中的customer_id(FK - 外键)引用,从而在关联记录之间建立了联系。在合并数据之前,了解主键和外键非常重要。它们提供逻辑结构,使我们能够准确地合并来自不同表的信息,这正是SQL JOIN操作的设计目的。在接下来的章节中,我们将了解如何在JOIN子句中使用这些键来获取组合数据集。