Skip to main content

数据库中的传递依赖

區塊鏈無法擴展:至少現在不能,但有希望(二) (六月 2025)

區塊鏈無法擴展:至少現在不能,但有希望(二) (六月 2025)
Anonim

数据库中的传递依赖关系是同一个表中导致函数依赖关系的值之间的间接关系。要达到第三范式(3NF)的标准化标准,必须消除任何传递依赖。

就其本质而言,传递依赖需要三个或更多属性(或数据库列),它们之间具有功能依赖性,这意味着表中的列A依赖于列B通过中间列C.

让我们看看这是如何工作的。

传递依赖性示例

作者

AUTHOR_ID作者Author_Nationality
Auth_001奥森斯科特卡安德的游戏美国
Auth_001奥森斯科特卡安德的游戏美国
Auth_002玛格丽特阿特伍德女仆的故事加拿大

在上面的AUTHORS示例中:

  • 书 → 作者 : 在这里, 书 属性决定了 作者 属性。如果您知道图书名称,则可以了解作者的姓名。然而, 作者 不确定 书 ,因为作者可以写多本书。例如,仅仅因为我们知道作者的名字Orson Scott Card,我们仍然不知道书名。
  • 作者 → Author_Nationality : 同样地, 作者 属性决定了 Author_Nationality ,但不是相反;仅仅因为我们知道国籍并不意味着我们可以确定作者。

但是这个表引入了传递依赖:

  • 书 → Author_Nationality: 如果我们知道图书名称,我们可以通过“作者”列确定国籍。

避免传递依赖

为了确保第三范式,我们删除传递依赖。

我们可以从Authors表中删除Book列并创建一个单独的Books表开始:

图书

Book_IDAUTHOR_ID
Book_001安德的游戏Auth_001
Book_001心灵的孩子Auth_001
Book_002女仆的故事Auth_002

作者

AUTHOR_ID作者Author_Nationality
Auth_001奥森斯科特卡美国
Auth_002玛格丽特阿特伍德加拿大

这个解决了吗?我们现在来检查我们的依赖关系:

书桌:

  • Book_ID → 书: 该 书 取决于 Book_ID .
  • 此表中没有其他依赖项,所以我们没问题。注意外键 AUTHOR_ID 通过其主键将此表链接到AUTHORS表 AUTHOR_ID 。我们创建了一种关系,以避免传递依赖,这是关系数据库的关键设计。

AUTHORS表:

  • AUTHOR_ID → 作者: 该 作者 取决于 AUTHOR_ID .
  • 作者 → Author_Nationality: 国籍可由作者确定。
  • AUTHOR_ID → Author_Nationality: 国籍可以从中确定 AUTHOR_ID 通过 作者 属性。我们仍然有传递依赖。

我们需要添加第三个表来规范化这些数据:

COUNTRIES

COUNTRY_ID国家
Coun_001美国
Coun_002加拿大

作者

AUTHOR_ID作者COUNTRY_ID
Auth_001奥森斯科特卡Coun_001
Auth_002玛格丽特阿特伍德Coun_002

现在我们有三个表,利用外键在表之间进行链接:

  • BOOK表的外键 AUTHOR_ID 将书籍链接到AUTHORS表中的作者。
  • AUTHORS表的外键 COUNTRY_ID 将作者链接到COUNTRIES表中的国家/地区。
  • COUNTRIES表没有外键,因为它不需要链接到此设计中的另一个表。

为什么传递依赖是不好的数据库设计

避免传递依赖关系有助于确保3NF的价值是什么?让我们再次考虑我们的第一个表,看看它创建的问题:

作者

AUTHOR_ID作者Author_Nationality
Auth_001奥森斯科特卡安德的游戏美国
Auth_001奥森斯科特卡心灵的孩子美国
Auth_002玛格丽特阿特伍德女仆的故事加拿大

这种设计可能导致数据异常和不一致,例如:

  • 如果你删除了两本书“心灵的孩子”和“安德的游戏”,你将完全从数据库中删除作者“奥森斯科特卡”和他的国籍。
  • 除非您还添加了一本书,否则无法将新作者添加到数据库中;如果作者尚未发表或您不知道她撰写的书的名称怎么办?
  • 如果“Orson Scott Card”改变了他的公民身份,则必须在他出现的所有记录中更改它。拥有同一作者的多个记录可能会导致数据不准确:如果数据录入人员没有意识到他有多个记录并且仅在一个记录中更改数据,该怎么办?
  • 你不能删除像“女仆的故事”这样的书,也不能完全删除作者。

这些只是为什么规范化和避免传递依赖性,保护数据和确保一致性的一些原因。