跳至主要内容

什么是传递依赖?

传递依赖是指数据库中的一个属性通过第三个属性间接依赖另一个属性,从而导致冗余。继续阅读,了解如何在数据库设计中识别并消除传递依赖。
· 5分钟 阅读

使用 AI 探索

在数据库中,当表中的一个属性依赖于另一个属性,而该属性又依赖于主键时,就会出现传递依赖。传递依赖是数据库规范化中的一个问题,因为它会导致数据问题,例如更新、插入和删除异常。我们将在本文中进行探讨。 

如果在阅读本文后,您想进一步学习,建议参加 DataCamp 的Database Design课程,熟悉关系型数据库以及如何在数据库中存储数据。还建议查看我们的Normalization in SQL教程,了解 SQL 中的各类范式——在此语境下,它是管理关系型数据库最常用的语言。

理解数据库中的传递依赖

在关系型数据库中,传递依赖是指一个属性通过中间属性间接依赖另一个属性。这意味着某一列的值可以由另外两列的值间接推导出来。请看下面名为 DataCamp_Programs 的表:

Course_or_Skill_TrackInstructorInstructor_Title
Data Manipulation in SQLMona KhalilData Scientist
SQL FundamentalsMona KhalilData Scientist
Introduction to SQLIzzy WeberData Coach

从该表可以看出:

  • Course_or_Skill_Track → Instructor:如果我们知道课程或技能路径,就能知道讲师。

  • Instructor 不 → Course_or_Skill_Track:有时讲师会教授多门课程或路径。

  • Instructor → Instructor_Title:每位讲师都有一个职称。

因此,Course_or_Skill_Track → Instructor_Title 属于传递依赖。 

为什么传递依赖会引发问题

传递依赖会导致数据库问题,主要涉及数据冗余、异常和不一致。

数据冗余

当同一数据在数据库中被不必要地重复存储时,就会产生数据冗余,带来低效。在 DataCamp_Programs 表的例子中,讲师的职称会在其教授的每门课程中重复存储。这种重复既浪费存储空间,也增加了维护难度。

数据异常

现在我们来看看更新、插入和删除方面的问题。

更新异常

由于冗余,数据的变更必须在多个位置同时应用,这就导致了更新异常。如果部分记录被更新、而其他被忽略,就会出现不一致。设想我们使用 SQL 查询更新 DataCamp_Programs 表,因为 Mona Khalil 的职称变更为 Lead Data Scientist。您需要手动更新所有出现其职称的行。如果哪怕漏掉一处,数据库中关于其当前职称的信息就会相互矛盾。 

Course_or_Skill_TrackInstructorInstructor_Title
Data Manipulation in SQLMona KhalilLead Data Scientist
SQL FundamentalsMona KhalilData Scientist
Introduction to SQLIzzy WeberData Coach

插入异常

当由于缺少其他必需数据而无法向数据库插入数据时,就会发生插入异常。在其他情况下,您也许能插入数据,但表的结构会迫使您包含无关、冗余或缺失的信息,如下例所示:

Course_or_Skill_TrackInstructorInstructor_Title
Data Manipulation in SQLMona KhalilData Scientist
SQL FundamentalsMona KhalilData Scientist
Introduction to SQLIzzy WeberData Coach
TBDLiam CooperData Analyst

删除异常

当删除一条记录时无意间把数据库中的有价值信息也删除了,就会发生删除异常。比如,删除包含 Izzy Weber 的记录会同时删除讲师职称,这可能导致数据丢失,因为系统中可能不再保留完整的职称集合。在这里,我们可能在非预期的情况下将 Data Coach 从系统中彻底删除了。

Course_or_Skill_TrackInstructorInstructor_Title
Data Manipulation in SQLMona KhalilData Scientist
SQL FundamentalsMona KhalilData Scientist

用 3NF 消除传递依赖

在数据库语境中,规范化是指组织数据以最大限度减少冗余并提升数据完整性。基于此,传递依赖通常在第三范式(3NF)的语境下讨论——这是一种通过消除依赖关系来解决传递依赖问题的数据库规范化技术。 

第三范式是数据库规范化的一个层级,旨在消除传递依赖,并确保每个非键属性只依赖于主键。这有助于防止冗余以及由传递依赖引起的错误。在对数据库架构进行规范化时,请考虑以下步骤。

识别传递依赖

要在数据库中发现传递依赖,可将过程分解如下:

  1. 检查主键上的函数依赖:首先识别所有属性直接依赖主键的函数依赖。这一步有助于您聚焦于表中的主要关系。
  2. 查找间接依赖:接着,检查是否存在非键属性(不属于主键的一部分)依赖于其他非键属性的情况。如果发现某个非键属性依赖另一个非键属性,而后者又依赖主键,那么您就识别出了一处传递依赖。
  3. 检验是否产生冗余或异常:最后,考虑这种间接依赖是否引入了数据冗余或使更新更为复杂。

拆分表

一旦识别出传递依赖,您需要通过拆分表来消除它们。应将表拆分为更小的表,使非键属性直接依赖于主键。同时,通过外键保持表与表之间的关系。

以下展示如何将 DataCamp_Programs 表拆分为两个表,以规范化并消除传递依赖。您将看到我们把表拆成两个,instructor 成为连接二者的键。   

表 1:courses_table

Course or Skill TrackInstructor
Data Manipulation in SQLMona Khalil
SQL FundamentalsMona Khalil
Introduction to SQLIzzy Weber

表 1:instructors_table

InstructorInstructor_Title
Mona KhalilData Scientist
Izzy WeberData Coach

该结构消除了此前通过 Instructor,使 Instructor_Title 依赖于 Course_or_Skill_Track 的传递依赖。现在,Instructor_Title 只依赖于 Instructor。

如何避免传递依赖

在设计数据库时,避免传递依赖对保持数据的高效、可扩展和完整至关重要。以下是最佳实践,可最大限度降低冗余、异常和不一致的风险。

  • 架构设计阶段的规范化:如果您从架构层面设计数据库,务必在早期就考虑第三范式(3NF)。这一方法通过应用规范化技术,有助于降低传递依赖。 
  • 定期进行架构审计:在创建数据库之后,应定期进行审计,以确保其不受传递依赖影响。
  • 避免过度简化关系:始终梳理清楚关系,并将不同实体正确分离到不同的表中以存储不同信息。

总结

数据库中的传递依赖是指表中的一个属性依赖另一个属性,而后者依赖主键。传递依赖会通过引入冗余、不一致和异常而影响数据库效率。作为开发者,识别并消除传递依赖对数据完整性至关重要。您还应在数据库设计阶段识别并消除传递依赖。实现第三范式(3NF)将有助于优化数据库并提升效率。

如果您想提升数据库设计技能,建议参加 DataCamp 的Creating PostgreSQL Databases课程,深入学习架构设计和数据库访问控制。最后,如果您希望在大数据场景下提升数据库管理技能,建议参加我们的Introduction to Data Modeling in Snowflake课程,进一步了解关系、维度建模和数据金库,以构建高效的云数据仓库。

Allan Ouko

作者

Allan Ouko

数据科学技术写作者,具备数据分析、商业智能和数据科学的一线实践经验。我撰写以行业为导向的实用内容,涵盖 SQL、Python、Power BI、Databricks 和数据工程,并以真实的分析工作为基础。我的写作兼顾技术深度与业务影响,帮助专业人士将数据转化为自信的决策。

传递依赖常见问答

函数依赖与传递依赖有什么区别?

函数依赖指某个属性直接依赖于主键。传递依赖指某个非键属性依赖于另一个非键属性,而后者又依赖于主键。

为什么传递依赖会带来问题?

传递依赖会导致数据冗余和异常,例如更新、插入和删除异常。

什么是数据规范化?

数据规范化是将数据库组织为表与列的过程,旨在减少数据冗余并提升数据完整性。

什么是第三范式(3NF)?

第三范式(3NF)是一种不包含传递依赖的规范化技术。在 3NF 中,每个非主属性必须只依赖于主键,确保不存在间接依赖。

主题