数据库表关系
了解数据库中表之间如何相互关联。
关系是表之间有意义的关联,这些表包含相关信息——它们是使数据库有用的原因。如果数据库中的表之间没有某种连接,那么您可能只是在使用不同的电子表格文件,而不是一个数据库系统。
正如我们在数据库简要概述中介绍的,数据库是表的集合,这些表有字段(也称为列)。每个表都包含一个称为实体(或主)键的字段,它标识该表中的行。通过告诉数据库一个表中的键值对应于另一个表中的键值,您就创建了这些表之间的关系;这些关系使得您可以在数据库中的不同表之间运行强大的查询。当一个表的实体键链接到第二个表时,它在该第二个表中被称为外键。
识别表之间所需的连接是数据建模和模式设计过程的一部分——也就是说,找出数据如何组合在一起以及如何准确配置表及其字段的过程。这个过程通常涉及创建表及其关系的视觉表示,称为实体关系图 (ERD),其中不同的符号指定了关系的类型。这些表之间的关系可以是:
思考表之间应如何相互关联也有助于确保数据完整性、数据准确性,并将冗余数据降至最低。
一对一关系
在**一对一**关系中,一个表中的一条记录只能对应另一个表中的一条记录(或者在某些情况下,没有记录)。一对一关系并不是最常见的,因为在许多情况下,您可以将相应的信息存储在同一个表中。是否将这些信息拆分到多个表中取决于您的整体数据模型和设计方法;如果您尽可能地保持表的焦点狭窄(例如在规范化数据库中),那么您可能会发现一对一关系很有用。
一对一关系示例
假设您正在整理公司的员工信息,并且还想跟踪每位员工的电脑。由于每位员工只有一台电脑,并且这些电脑不共享,您可以在Employee
表中添加字段来保存每台电脑的品牌、年份和操作系统等信息。然而,从语义角度来看,这可能会变得混乱——电脑信息真的属于员工信息表吗?这由您来决定,但另一种选择是创建一个Computers
表,与Employee
表建立一对一关系,如下图所示:
在这种情况下,我们Employee
表的实体键充当Computers
表的外键。您可能有一些尚未分配给员工的电脑,这种建模确保您仍然可以在Computer
表中保留它们的记录。如果员工离职,您只需更新一个字段,并且可以轻松地将电脑链接到新员工。
ERD 中用于连接表的线条(称为乌鸦脚符号)的具体格式各不相同;有时您会看到表示一对一关系的纯线条,有时这些线条会有交叉影线。
一对一关系也适用于安全目的,例如当您希望将敏感客户信息存储在单独的表中,并使用外键将其链接到您的主Customers
表时。
一对多关系
**一对多**关系是数据库中最常见的表间关系类型。在一对多(有时也称为多对一)关系中,一个表中的一条记录对应另一个表中的零条、一条或多条记录。
一对多关系示例
例如,考虑 Metabase 示例数据库中客户及其订单的表,其中People
表中的一条记录可以链接到Orders
表中的多条记录。在这种情况下,一位客户可以下多个订单,这些多个订单记录都将链接回People
表中的一条记录。这种连接通过User_ID
字段进行编码,该字段是People
表中的主键,也是Orders
表中的外键。下图显示了这两个表之间的关系:
虽然一个人可以关联多个订单,但反之则不然——订单只关联到People
表中的一条记录,并且不会有多个客户。
多对多关系
**多对多**关系表示一个表中的多条记录与另一个表中的多条记录相关联。这些记录可能只与一条记录(或根本没有)相关联,但关键是它们可以并且通常会链接到多条记录。多对多关系在实际数据库使用场景中并不常见,因为遵循规范化通常涉及将多对多关系分解为独立的、更集中的表。
事实上,您的数据库系统甚至可能不允许直接创建多对多关系,但您可以通过创建第三个表(称为**连接表**)来规避此问题,并在该表和您的两个起始表之间创建一对多关系。
从这个意义上说,Metabase 示例数据库中的Orders
表充当连接表,在People
和Products
之间创建了中间链接。示例数据库的 ERD 看起来如下图所示,其中每个关系都由连接表的线条类型指定:
严格来说,Products
和Orders
表之间存在一对多关系,即一个产品可以关联多个订单。但根据我们虚构公司的数据库,人们似乎只订购单一产品(无论出于何种原因,他们会购买五台轻便羊毛电脑)。一个真实世界(或许更具商业头脑)的数据库实现可能会在两者之间包含一个连接表,从而使订单可以包含许多不同的产品。