数据库,如何确定功能依赖性以及是否在BCNF中?

时间:2018-11-21 14:22:07

标签: database database-design functional-dependencies bcnf

我目前正在研究这个问题,以确定它是哪种正常形式,因此我必须列出功能上的依赖关系。我制定了解决方案,但仍然对此有疑问。

  

在最后一年的项目选择过程中,学生应选择一个   他/她的项目的研究主题。允许学生选择   相同的研究主题。对于每个研究主题,主管都是   分配监督。一位主管最多可以监督两名   不同的研究主题,每个研究主题可以分配给   不同的主管。对于每个研究主题,主管   在监督下,安排咨询日供学生见面   并与主管讨论。

有关最后一年项目选择的信息存储在以下关系表中: FINALYEARPROJECT(主管,研究主题,咨询日, 学生)

这些是我列出的功能依赖项:

学生→研究主题,咨询日,主管

  • 学生是候选键。

主管,研究课题,学生→咨询日

问题1: 从学生身上,我可以找到所有属性。但是随后有了(主管,研究主题,学生),我也可以找到咨询日。但是,这些只是超级键,而不是候选键。那应该是依赖吗?

问题2: 假设我的依存关系是正确的,我可以推导该关系表在BCNF中。但是在我的演讲笔记中,

  

Boyce-Codd范式(BCNF)的定义指出一个关系   当且仅当每个行列式都是候选键时,才在BCNF中。

这与我在网上(例如Wiki)上发现的非常不同:

  

当且仅当针对以下情况时,关系模式R才是Boyce-Codd范式   它的每个依存关系X→Y,以下至少之一   条件成立:

Glide.with(getApplicationContext()).load(user_image).apply(new RequestOptions().override(100, 100)).into(ImageView);

因此,根据我的书面记录,现在,在找到依赖项之后,该表将不在BCNF中,因为(主管,researchTopic,student)不是候选键,而只是一个超键。但是,如果根据Wiki的规定,该表将位于BCNF中,因为所有行列式都是超键。

2 个答案:

答案 0 :(得分:1)

您引用的BCNF的定义都没有提及哪个功能集,用于检查标准形式的满意度,但这很重要。

您知道,给定一组功能依赖项(例如,通过对问题的推理而发现),存在许多等价集,或者更确切地说,有许多对等集;例如,一组FD的最小或标准覆盖范围是没有冗余依赖项也没有多余属性的覆盖范围,并且在每个依赖项的右侧都有一个属性。

因此,实际上,很容易证明提及超键的定义(例如Wiki定义)等同于提及候选键的定义(例如您的讲义中的)。所考虑的依赖是最小覆盖的依赖。实际上,在最小覆盖范围内,不存在琐碎的依赖关系,并且对于定义,没有严格的超级键(即由候选键加上一组非空属性组成的超级键)可以作为任何依赖关系的左侧部分出现最小的封面。

因此,在检查标准格式时,最好先找到给定依赖项的最小覆盖范围。

对于涉及示例功能依赖的问题,给定问题的具体说明,对于我来说,尚不清楚学生是否选择了reasearch主题然后可以去任何主管进行研究讨论该主题,或者也分配给特定主管。当然,这两种情况下的依赖关系是不同的。

答案 1 :(得分:1)

  

学生应选择一个研究主题

'use strict';

// Generating a "whitelist" wherein you only want a specific folder to be
// affected requires following .gitignore-style rules.
// https://github.com/prettier/prettier/issues/3328
//
// Handcrafting these rules is hard to reason about and error-prone, so I'm
// going to generate them.
// See: https://github.com/prettier/prettier/issues/3328
// And: https://git-scm.com/docs/gitignore
//

const path = require('path');

const whitelistDir = '/themes/simple/src/';

function generateIgnoreRule(dir) {
    let output = '# Auto-generated by ' + path.basename(__filename) + '\n';
    output += '# Exclude everything except `' + dir + '`\n';
    // Add exclude everything rule
    output += '/*' + '\n';

    // Split by path
    const parts = dir.split('/');
    if (parts[0] === '') {
        // Remove first item if its blank
        parts.shift();
    }
    if (parts[parts.length - 1] === '') {
        // Remove last item if its blank
        parts.pop();
    }

    let totalPart = '';
    for (let part of parts) {
        totalPart += '/' + part;
        output += '!' + totalPart + '\n';
        if (part !== parts[parts.length - 1]) {
            output += totalPart + '/*' + '\n';
        }
    }
    return output;
}

console.log(generateIgnoreRule(whitelistDir));
console.log(
    '\nCopy the above rules out of the console output and paste into your .gitignore / .prettierignore'
);

因为每个学生只有一个研究主题,并且这是这种关系中仅有的两个属性,所以我们知道学生是唯一的,因此是候选关键字。

  

允许学生选择相同的研究主题。

这告诉我们研究主题在同一关系中不是唯一的,并且不能成为候选关键字。

  

对于每个研究主题,都指定了主管进行监督。

student -> research-topic
  

主管可能要监督两个不同的研究主题

因此,主管在这个关系中不是唯一的,并且不能成为候选密钥。

  

每个研究主题可以分配给不同的主管。

好,修改(第一次)

research-topic -> supervisor

每个研究人员都有一个以上的主题,每个主题都有一个以上的研究员。

  

对于主管监督的每个研究课题,为学生分配咨询日

第二次修订:

research-topic, supervisor -> {}

这有点混乱,也许是有意这样做,以解决问题。由于每个学生只有一个研究主题,因此对于每个研究主题都是红鲱鱼。我们同样可以说:

第三次修订:

research-topic, supervisor, student -> consultation-day

research-topic, supervisor -> {}

没有必要将主题放在第三个关系的关键中,因为当学生与主管会面时,它将是学生唯一的主题。如果一个学生可能有多个主题,我们必须将其添加到关系中,以了解咨询日的议程。

  

与主管见面并讨论。

呼叫这三个关系的学生,主管和咨询。我留给您写一个联接来产生{学生,主题,主管,日},并证明学生与主管的自然联接仅产生1行。

我所做的只是将陈述的要求表达为依赖关系。每个依赖项都被最小化地捕获。本质上就是BCNF。

您的学生表不是BCNF。没有任何地方说明学生选择或分配了主管。