数据库中的传递依赖关系是导致功能相关。达到标准化标准第三范式(3NF),您必须消除任何传递依赖性。
从本质上讲,传递依赖项需要三个或更多属性(或数据库列)之间有一个函数依赖关系,这意味着表中的列a通过中间的列c依赖于列B。让我们看看这是如何工作的。
传递依赖的例子
作者
Author_ID | 作者 | 书 | Author_Nationality |
---|---|---|---|
Auth_001 | 奥森·斯科特卡 | 安德的游戏 | 美国 |
Auth_001 | 奥森·斯科特卡 | 心灵之子 | 美国 |
Auth_002 | 玛格丽特·阿特伍德 | 婢女的故事 | 加拿大 |
在上面的AUTHORS示例中:
- 书→作者:在这里,书属性决定了作者属性。如果你知道书的名字,你就能知道作者的名字。然而,作者不确定书,因为一个作者可以写多本书。例如,仅仅因为我们知道作者的名字奥森·斯科特·卡德,我们仍然不知道书的名字。
- 作者→Author_Nationality:同样,作者属性决定了Author_Nationality,而不是反过来;仅仅因为我们知道国籍并不意味着我们可以确定作者。
但是这个表引入了一个传递依赖:
- 书→Author_Nationality:如果知道书名,就可以通过Author列确定国籍。
避免传递依赖关系
为了确保第三范式,让我们移除传递依赖项。
我们可以先从Authors表中删除Book列,然后创建一个单独的Books表:
书
Book_ID | 书 | Author_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。我们创建了一个关系来避免传递依赖,这是关系数据库的关键设计。
作者表:
- Author_ID→作者:的作者取决于Author_ID。
- 作者→Author_Nationality:国籍可由作者决定。
- Author_ID→Author_Nationality:国籍可以从Author_ID通过作者属性。我们仍然有一个传递依赖。
我们需要添加第三个表来规范化这个数据:
国家
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表没有外键,因为在此设计中它不需要链接到另一个表。
为什么传递依赖是糟糕的数据库设计
避免传递依赖来帮助确保3NF的价值是什么?让我们再次考虑我们的第一个表,看看它产生的问题:
作者
Author_ID | 作者 | 书 | Author_Nationality |
---|---|---|---|
Auth_001 | 奥森·斯科特卡 | 安德的游戏 | 美国 |
Auth_001 | 奥森·斯科特卡 | 心灵之子 | 美国 |
Auth_002 | 玛格丽特·阿特伍德 | 婢女的故事 | 加拿大 |
这种设计可能导致数据异常和不一致,例如:
- 如果你删除了《心灵的孩子》和《安德的游戏》这两本书,你就从数据库中完全删除了作者奥森·斯科特·卡德和他的国籍。
- 您不能向数据库添加一个新的作者,除非您同时添加了一本书;如果作者还没有出版,或者你不知道她写的书的名字怎么办?
- 如果"奥森·斯科特·卡德"改变了他的国籍,你就得在他出现的所有记录中更改他的身份。与同一作者有多个记录可能导致不准确的数据:如果数据输入人员没有意识到他有多个记录,而只更改了一个记录中的数据,该怎么办?
- 你不可能删除像《使女的故事》这样的书,而不同时完全删除作者。
这些只是一些原因归一化,避免传递依赖,保护数据并确保一致性。
谢谢你告诉我们!
告诉我们为什么!