什么是数据库中的一对多关系?

一对多关系是最常见的数据库关系之一。如果您想了解何时以及如何使用一对多关系,那么本文是一个很好的起点。

您肯定会使用一对多关系将信息存储在任何关系数据库中,无论您是在设计企业级软件还是只是创建一个简单的数据库来跟踪您叔叔的邮票收藏。

关系模型简介

关系数据库是任何现代事务应用程序的核心组件。关系模型由表(按行和列组织的数据)组成,这些表至少有一个标识每行的唯一键。每个表表示一个实体。以下示例显示了这一点,这是表示客户订单的表的非常简单版本:

什么是关系,我们为什么需要它们?

如果我们更深入地看一下前面示例中使用的表,我们将看到它并不真正表示完整的订单。它没有您期望它拥有的所有信息。您会注意到,它不包括与下订单的客户相关的任何数据,也没有关于订购的产品或服务的任何信息。

我们应该做些什么来完成这个设计来存储订单数据?我们是否应该将客户和产品信息添加到 Order 表中?这将需要为客户名称、税务标识符、地址等添加新列(属性),如下所示:

"Order ID""Order Date""Order Amount"Customer"Customer Address""Customer Phone""Tax Identifier"
1jun-23$10 248,15International Services Ltd1247 St River Blvd, Charlotte, NC(555) 478-8741IS789456
2jun-27$14 785,45World Master Importing Inc.354 Mountain Hill Rd, Los Angeles, CA(555) 774-8888WM321456
3jul-01$7 975,00First State Provisioning Llc444 North Highway, Houston, TX(555) 698-7411FS947561
4jul-03$6 784,25International Services Ltd1247 St River Blvd, Charlotte, NC(555) 478-8741IS789456
5jul-07$21 476,10World Master Importing Inc.354 Mountain Hill Rd, Los Angeles, CA(555) 774-8888WM321456
6jul-12$9 734,00First State Provisioning Llc444 North Highway, Houston, TX(555) 698-7411FS947561
7jul-17$14 747,45World Master Importing Inc.354 Mountain Hill Rd, Los Angeles, CA(555) 774-8888WM321456
8jul-21$19 674,85International Services Ltd1247 St River Blvd, Charlotte, NC(555) 478-8741IS789456

如果我们这样做,我们很快就会遇到问题。大多数客户下多个订单,因此此系统将存储客户信息多次,每个客户的每个订单一次。这似乎不是一个明智的举动。

此外,当客户更改其电话号码时会发生什么?如果有人需要给客户打电话,他们可能会在以前的订单上找到旧号码 - 除非有人用新信息更新数百(甚至数千)个现有订单。任何其他变化也是如此。

关系模型要求我们将每个实体定义为一个单独的表,并在它们之间建立关系。将所有信息存储在单个表中是行不通的。

表之间有几种类型的关系,但最常见的可能是一对多关系,通常写为 1:N。这种关系意味着表(通常称为父表)中的一行可以与另一个表(通常称为子表)中的许多行具有关系。一对多关系的一些常见示例如下:

  • 汽车制造商生产许多不同的车型,但特定的汽车型号仅由一家汽车制造商制造。
  • 一个客户可以进行多次购买,但每次购买都是由单个客户进行的。
  • 一家公司可以有多个电话号码,但一个电话号码属于一家公司。

表之间还有其他类型的关系;如果您想了解有关它们的更多信息,请参阅有关多对多关系的文章。

回到我们的初始订单示例,客户表将是父表,订单表是子表;一个客户可以有多个订单,而一个订单可以属于单个客户。

请注意,一对多定义允许父表中的一行与每个子表上的许多行相关联,但它不需要它。实际上,该设计允许客户拥有零订单(即尚未进行第一次购买的新客户),一个订单(已进行单次购买的相对较新的客户)或多个订单(频繁的客户)。

在 ER 图中显示一对多关系

让我们看一个更完整的示例,该示例使用 ER(或实体关系)图的简单客户订购系统。下面是模型: 

这是一个更逼真的设计。您会注意到图中有新的实体(表),该图现在包含“客户”、“订单”、“订单详细信息”和“产品”。但是,您注意到的最重要的事情是,表之间现在存在关系

在数据库模型中,关系由连接两个实体的线表示。这些关系的特征由不同的连接器表示:

  • 当存在一条垂直线时,离该连接线最近的实体只有一行受关系影响。它是一对多中的“一”。
  • 当存在看起来像鱼尾纹的多行连接器时,离该连接器最近的实体具有受关系影响的多行;它是“许多”。

查看图像并了解符号,很容易理解该图定义了每个订单可以有多个订单详细信息,并且每个订单详细信息属于单个订单

在表之间实现一对多关系

若要定义两个表之间的一对多关系,子表必须引用父表上的一行。定义它所需的步骤是:

  1. 向子表中添加一列,用于存储主标识符的值。(实际上,大多数数据库引擎都允许它是父表中的任何唯一键,而不仅仅是主键。根据您的业务需求,该列可以定义为强制性的;即便如此,通常也会创建外键列

注意:最好使引用列的名称与引用(父)表中的名称相同。这使得理解这种关系变得更加容易。

  1. 在子表上添加外键约束。这表示此新列中存储的每个值都引用父表上的一行。

  1. 向子表中添加行时,引用列的值必须与父表中的一个(且只有一个)值匹配。(这就是为什么必须引用构成主键或唯一键的列或一组列的原因)。
  2. 如果有人尝试从父表中删除某一行,或者尝试修改用作引用的唯一/主键的值,并且存在引用该行的子表,则操作将失败。

这两个功能可确保数据库保持其完整性。没有机会创建引用不存在的客户的订单,也没有机会删除已有订单的客户。

创建外键

外键语法通常取决于目标数据库引擎。定义逻辑模型后,可以使用“生成物理模型...”功能,将您的(与数据库无关的)模型转换为与您的数据库提供程序匹配的物理模型。Vertabelo 还将生成所需的 SQL 脚本,该脚本将允许您在目标数据库中创建表和关系。

1:N 关系的一些实际示例

现在,让我们回顾一下现实世界一对多关系的一些示例。

使用主键的一对多关系

这可能是定义一对多关系时最常见的方案。子表使用父表的主键值来建立关系。

此示例描述基本的联机流式处理服务。让我们回顾一下每个表中存储的内容,以及它们与模型中其他表的关系:

  1. 每个 ServiceType 定义帐户的“行为”方式(例如,如果帐户启用了 Full HD,则有多少用户可以同时连接到系统等)。它与其他实体有一个关系:
    • 帐户的一对多关系,这意味着每个服务类型可以有多个该类型的帐户。
  2. 每个帐户存储有关一个客户的信息。它与其他实体有两种直接关系:
    • 如上所述,每个帐户都属于一个服务类型
    • 此表与 Profile 表具有一对多关系,这意味着多个用户可以使用同一帐户连接到我们的系统。
  3. 每个配置文件代表我们系统中的一个用户。它与其他实体有两种关系:
    • 每个配置文件都属于一个帐户。这允许所有家庭成员(或一群朋友)共享同一个帐户,而每个人都有自己的个人属性(例如个人资料名称)。
    • 每个个人资料都有一个唯一的头像
  4. 每个头像都是一个图像,使我们能够快速识别每个帐户用户。它与另一个实体有一个关系:
    • 配置文件的一对多关系,这意味着可以将单个头像分配给不同帐户上的配置文件。

 

与自然或代理唯一键的一对多关系

代理主键的使用是一种被广泛接受的表建模方式。(代理主键由数据库生成,没有实际的业务价值。此方法生成的密钥更易于使用,并在需要更改时增加了一些灵活性。

但是,在某些情况下 - 例如,当我们需要与外部系统交互时 - 使用数据库中生成的密钥是一种糟糕的方法。对于这些方案,通常最好使用自然键,这些自然键是唯一值,是所存储实体的一部分,而不是由我们的数据库自动生成的。

以下示例表示组织的基本数据模型,该模型跟踪车辆(即汽车的品牌、型号、颜色和年份)、其所有者以及任何相关的运输违规行为。当我们定义它时,我们使用代理主键来建立车辆与品牌,车型和车主之间的关系,因为所有这些信息都由我们的系统内部处理。

在这个系统中,另一个城市的警察如何报告使用我们的车辆主键()非法停放的汽车?停放的车辆上不会自然提供此类信息,但车牌就在那里。这意味着从外部来源(在本例中为国家/地区的任何警察局)接收和关联信息的最简单方法是使用自然唯一密钥而不是代理主密钥。VehicleID

此处提供了此 SQL Server 逻辑关系图的物理实现:

 

同一表上的一对多关系

前面的示例重点介绍两个或多个表之间的关系,但也有一些情况是,同一表的行之间会出现这种关系。这种一对多关系也称为等级关系;它在许多系统中用于表示树状结构,即组织结构图,总帐科目或产品及其组成部分。

第一次需要创建这种结构时,您会忍不住为层次结构中的每个级别定义一个表,如下图所示:

 这种方法存在许多问题:

  • 所有表几乎完全相同,并存储相同的信息。
  • 如果您的组织添加新级别,则必须修改数据模型并添加新表、新外键等。
  • 如果员工获得晋升,您需要从一个表中删除他们,然后将其插入到另一个表中。

因此,对这种结构进行建模的最佳方法是使用引用自身的单个表,如下图所示:

 

在这里,我们看到一个 Employee 表和一个名为 的列。该列引用同一组织中作为当前员工的主管/经理的另一名员工。EmployeeID_Manager

我添加了后缀来区分当前行的 ID 和管理器的 ID。(我们可以改用,但我更喜欢保留引用列的原始名称,并且在两者位于同一表中的情况下,添加一个后缀来解释它实际具有的角色)。_ManagerManagerID

了解层次结构关系比其他一对多关系更复杂。但是,如果您忘记了存储所有信息的表,并想象实际上有不同的表,每个表都代表层次结构中的一个级别,则可视化起来会更容易一些。想象一下,您在两个实体之间建立关系,然后将它们组合成一个实体。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关系数据库和NoSQL数据库 什么是NoSQL 大家有没有听说过“NoSQL”呢?近年,这个词极受关注。看到“NoSQL”这个词,大家可能会误以为是“No!SQL”的缩写,并深感愤怒:“SQL怎么会没有必要了呢?”但实际上,它是“Not Only SQL”的缩写。它的意义是:适用关系数据库的时候就使用关系数据库,不适用的时候也没有必要非使用关系数据库不可,可以考虑使用更加合适的数据存储。 为弥补关系数据库的不足,各种各样的NoSQL数据库应运而生。 为了更好地了解本书所介绍的NoSQL数据库,对关系数据库的理解是必不可少的。那么,就让我们先来看一看关系数据库的历史、分类和特征吧。 关系数据库简史 1969年,埃德加•弗兰克•科德(Edgar Frank Codd)发表了划时代的论文,首次提出了关系数据模型的概念。但可惜的是,刊登论文的《IBM Research Report》只是IBM公司的内部刊物,因此论文反响平平。1970年,他再次在刊物《Communication of the ACM》上发表了题为“A Relational Model of Data for Large Shared Data banks”(大型共享数据库关系模型)的论文,终于引起了大家的关注。 科德所提出的关系数据模型的概念成为了现今关系数据库的基础。当时的关系数据库由于硬件性能低劣、处理速度过慢而迟迟没有得到实际应用。但之后随着硬件性能的提升,加之使用简单、性能优越等优点,关系数据库得到了广泛的应用。 通用性及高性能 虽然本书是讲解NoSQL数据库的,但有一个重要的大前提,请大家一定不要误解。这个大前提就是“关系数据库的性能绝对不低,它具有非常好的通用性和非常高的性能”。毫无疑问,对于绝大多数的应用来说它都是最有效的解决方案。 突出的优势 关系数据库作为应用广泛的通用型数据库,它的突出优势主要有以下几点: 保持数据的一致性(事务处理) 由于以标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处) 可以进行JOIN等复杂查询 存在很多实际成果和专业技术信息(成熟的技术) 这其,能够保持数据的一致性是关系数据库的最大优势。在需要严格保证数据一致性和处理完整性的情况下,用关系数据库是肯定没有错的。但是有些情况不需要JOIN,对上述关系数据库的优点也没有什么特别需要,这时似乎也就没有必要拘泥于关系数据库了。 关系数据库的不足 不擅长的处理 就像之前提到的那样,关系数据库的性能非常高。但是它毕竟是一个通用型的数据库,并不能完全适应所有的用途。具体来说它并不擅长以下处理: 大量数据的写入处理 为有数据更新的表做索引或表结构(schema)变更 字段不固定时应用 对简单查询需要快速返回结果的处理 。。。。。。 NoSQL数据库 为了弥补关系数据库的不足(特别是最近几年),NoSQL数据库出现了。关系数据库应用广泛,能进行事务处理和JOIN等复杂处理。相对地,NoSQL数据库只应用在特定领域,基本上不进行复杂的处理,但它恰恰弥补了之前所列举的关系数据库的不足之处。 易于数据的分散 如前所述,关系数据库并不擅长大量数据的写入处理。原本关系数据库就是以JOIN为前提的,就是说,各个数据之间存在关联是关系数据库得名的主要原因。为了进行JOIN处理,关系数据库不得不把数据存储在同一个服务器内,这不利于数据的分散。相反,NoSQL数据库原本就不支持JOIN处理,各个数据都是独立设计的,很容易把数据分散到多个服务器上。由于数据被分散到了多个服务器上,减少了每个服务器上的数据量,即使要进行大量数据的写入操作,处理起来也更加容易。同理,数据的读入操作当然也同样容易。 提升性能和增大规模 下面说一点题外话,如果想要使服务器能够轻松地处理更大量的数据,那么只有两个选择:一是提升性能,二是增大规模。下面我们来整理一下这两者的不同。 首先,提升性能指的就是通过提升现行服务器自身的性能来提高处理能力。这是非常简单的方法,程序方面也不需要进行变更,但需要一些费用。若要购买性能翻倍的服务器,需要花费的资金往往不只是原来的2倍,可能需要多达5到10倍。这种方法虽然简单,但是成本较高。 另一方面,增大规模指的是使用多台廉价的服务器来提高处理能力。它需要对程序进行变更,但由于使用廉价的服务器,可以控制成本。另外,以后只要依葫芦画瓢增加廉价服务器的数量就可以了。 不对大量数据进行处理的话就没有使用的必要吗? NoSQL数据库基本上来说为了“使大量数据的写入处理更加容易(让增加服务器数量更容易)”而设计的。但如果不是对大量数据进行操作的话,NoSQ

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值