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(即传递依赖)
现在出现问题:
French和English课程,那么您也将删除他们的教师John Doe,他的电话号码将永远丢失.Instructor除非您Course先为他添加一个,否则无法在数据库中添加新内容,或者您可以复制Instructors table更糟糕的数据.John Doe更改了他的电话号码,那么你将不得不用新信息更新他教授的所有课程,这些课程很容易出错.Birth Date字段Courses.这听起来合乎逻辑吗?为什么首先要在课程表中保留教师信息.Bra*_*vic 10
表达3NF的一种方法是:
所有属性都应该取决于密钥,整个密钥以及密钥.
传递依赖性X-> 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原则的另一种表达方式.