传递依赖有什么问题?

Sim*_*ely 26 sql database database-design transitive-dependency

我的数据库设计中有一些传递依赖.我的上司告诉我,这些可能会导致错误.我发现很难找到资源,告诉我这些依赖项将如何导致错误.他们会引起什么样的问题?

我不是在争论这个事实,只是渴望了解它们可能导致什么样的问题.

编辑更多详细信息:

来自维基百科:

传递依赖
传递依赖是间接函数依赖,其中X→Z仅由X→Y和Y→Z组成.

Son*_*ngo 51

我将通过一个例子来解释:

-------------------------------------------------------------------
|  Course  |    Field     |   Instructor   |  Instructor Phone    |
-------------------------------------------------------------------
|  English |  Languages   |  John Doe      |     0123456789       |
|  French  |  Languages   |  John Doe      |     0123456789       |
|  Drawing |  Art         |  Alan Smith    |     9856321158       |
|  PHP     |  Programming |  Camella Ford  |     2225558887       |
|  C++     |  Programming |  Camella Ford  |     2225558887       |
-------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
  • 如果你有Course,你可以很容易地得到它Instructor这样Course ->Instructor.
  • 如果你有一个Instructor你无法得到它,Course因为他可能会教不同的课程.
  • 如果你有一个Instructor,你可以很容易地得到他Phone这样Instructor->Phone.

这意味着,如果你有一个Course那么你可以得到Instructor Phone哪个意思 Course ->Instructor Phone(即传递依赖)

现在出现问题:

  1. 如果您同时删除了FrenchEnglish课程,那么您也将删除他们的教师John Doe,他的电话号码将永远丢失.
  2. Instructor除非您Course先为他添加一个,否则无法在数据库中添加新内容,或者您可以复制Instructors table更糟糕的数据.
  3. 如果教练John Doe更改了他的电话号码,那么你将不得不用新信息更新他教授的所有课程,这些课程很容易出错.
  4. 除非删除他教授的所有课程或将其所有字段设置为null,否则无法从数据库中删除教师.
  5. 如果您决定保留教师的出生日期怎么办?您必须向表中添加一个Birth Date字段Courses.这听起来合乎逻辑吗?为什么首先要在课程表中保留教师信息.


Bra*_*vic 10

表达3NF的一种方法是:

所有属性都应该取决于密钥,整个密钥以及密钥.

传递依赖性X-> Y-> Z违反了该原则,导致数据冗余和潜在的修改异常.


让我们打破这个:

  1. 根据定义,对于函数依赖性X-> Y-> Z也是可传递的,X <-Y必须成立.
  2. 如果Y是键,则X <-Y将保持,因此Y不能成为键.(FOOTNOTE1)
  3. 由于Y不是键,因此任何给定的Y可以在多行中重复.
  4. Y-> Z意味着所有持有相同Y的行也必须保持相同的Z. (FOOTNOTE2)
  5. 在几行中重复相同的(Y,Z)元组不会向系统提供任何有用的信息.这是多余的.

简而言之,由于Y不是关键而Y-> Z,我们违反了3NF.

裁员导致修饰的异常(如更新一些,但不是所有的 "连接"到相同的Y的ZS基本上破坏的数据,因为你已经不知道哪个副本是正确的).这通常是通过将原始表拆分拆分成两个表,将含有{X,Y}和其它其它含{Y,Z},这样一个,Y可以是在所述第二表中的键和Z不再重复.

另一方面,如果X <-Y确实成立(即X-> Y-> Z不可传递),那么我们可以保留单个表,其中X和Y都是键.在这种情况下,Z不会不必要地重复.

(FOOTNOTE1)键是一组(最小)属性,它在功能上确定关系中的所有属性.基本原理:如果K是一个键,则不能有多个具有相同K值的行,因此任何给定的K值始终与每个其他属性的一个值相关联(假设为1NF).根据定义(参见FOOTNOTE2),"与一个相关联"与"处于功能依赖"是相同的.

(FOOTNOTE2)根据定义,Y-> Z当且仅当每个Y值恰好与一个Z值相关联时.


例:

假设每条消息只有一个作者,并且每个作者只有一个主电子邮件,尝试在同一个表中表示消息和用户将导致重复的电子邮件:

MESSAGE                         USER    EMAIL
-------                         ----    -----
Hello.                          Jon     jon@gmail.com
Hi, how are you?                Rob     rob@gmail.com
Doing fine, thanks for asking.  Jon     jon@gmail.com
Run Code Online (Sandbox Code Playgroud)

(实际上,这些将是MESSAGE_IDs,但让我们在这里保持简单.)

现在,如果Jon决定将他的电子邮件更改为"jon2@gmail.com",会发生什么?我们将需要更新乔恩的行.如果我们只更新一个,那么我们有以下情况......

MESSAGE                         USER    EMAIL
-------                         ----    -----
Hello.                          Jon     jon2@gmail.com
Hi, how are you?                Rob     rob@gmail.com
Doing fine, thanks for asking.  Jon     jon@gmail.com
Run Code Online (Sandbox Code Playgroud)

......我们不再知道Jon的哪一封电子邮件是正确的.我们基本上丢失了数据!

这种情况特别糟糕,因为我们没有声明性约束来强制DBMS强制执行这两个更新.客户端代码具有错误,并且可能在不太考虑并发环境中可能发生的复杂交互的情况下编写.

但是,如果你拆分表...

MESSAGE                         USER
-------                         ----
Hello.                          Jon 
Hi, how are you?                Rob 
Doing fine, thanks for asking.  Jon 

USER    EMAIL
----    -----
Jon     jon@gmail.com
Rob     rob@gmail.com
Run Code Online (Sandbox Code Playgroud)

...现在只有一行知道Jon的电子邮件,所以模棱两可是不可能的.

顺便说一下,所有这些都可以被视为DRY原则的另一种表达方式.


Car*_*ron 5

如果你的表中存在传递依赖,那么它就不符合3NF; 因此表中存在冗余数据的可能性很高.检查这一点以澄清这个概念.