这是Boyce-Codd NF的关系吗?

时间:2018-06-10 02:12:29

标签: database relational-database database-normalization

我有一个R(a,b,c,d)关系,其中(a,b)是主键,所以我有决定因素a,b -> c,d。 除此之外,我还有以下决定因素:a,c -> b,da,d -> b

我们可以确定这种关系是在3NF中。 我想知道它是否在BCNF。我正在使用BCNF的定义来识别:

  

如果它在3NF中,则关系在BCNF中,并且没有行列式X -> Y,例如X是非关键属性,Y是关键字的一部分(或整体)

例如,

在我的情况下不适用于行列式a,d -> b。另一个定义是

  

对于每个非平凡FD(X-> A)满足,关系R在BCNF中   由R满足以下条件:

     

(a)X是R

的超级密钥

这使我在a,d->b中明确表示(a,d)不是超级钥匙(也不是钥匙),但我们(a,d)明确指出了#include <QtSql> #include "scoremodel.h" #include "mainwindow.h" //MainWindow::sqlToQueryScore #include <QDebug> ScoreModel::ScoreModel(QObject *parent) : QSqlQueryModel(parent) { } Qt::ItemFlags ScoreModel::flags( const QModelIndex &index) const { Qt::ItemFlags flags = QSqlQueryModel::flags(index); if (index.column() != 0 && index.column() != 11) flags |= Qt::ItemIsEditable; return flags; } bool ScoreModel::setData(const QModelIndex &index, const QVariant &value, int /* role */) { if (index.column() == 0 || index.column() == 11) return false; QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0); int id = data(primaryKeyIndex).toInt(); qDebug()<<"id:"<<id; clear(); bool ok; switch(index.column()){ case 1: ok = setYear(id,value.toString()); case 2: ok = setStudentName(id,value.toString()); case 3: ok = setStudentClass(id,value.toString()); case 4: ok = setTestTime(id,value.toString()); case 5: ok = setTestSubject(id,value.toString()); case 6: ok = setTestType(id,value.toString()); case 7: ok = setTestScore(id,value.toString()); case 8: ok = setStudyPeriod(id,value.toString()); case 9: ok = setTestContent(id,value.toString()); case 10: ok = setTeacherRemark(id,value.toString()); default: ok = false; } refresh(); return ok; } void ScoreModel::refresh() { qDebug()<<"sqlToQueryScore in refresh:"<<MainWindow::sqlToQueryScore; setQuery(MainWindow::sqlToQueryScore); setHeaderData(0, Qt::Horizontal, tr("序号")); setHeaderData(1, Qt::Horizontal, tr("年份")); setHeaderData(2, Qt::Horizontal, tr("学生姓名")); setHeaderData(3, Qt::Horizontal, tr("学生班级")); setHeaderData(4, Qt::Horizontal, tr("测试时间")); setHeaderData(5, Qt::Horizontal, tr("测试科目")); setHeaderData(6, Qt::Horizontal, tr("测试类型")); setHeaderData(7, Qt::Horizontal, tr("测试成绩")); setHeaderData(8, Qt::Horizontal, tr("学习周期")); setHeaderData(9, Qt::Horizontal, tr("测试内容")); setHeaderData(10, Qt::Horizontal, tr("教师评语")); setHeaderData(11, Qt::Horizontal, tr("数据插入时间")); } bool ScoreModel::setYear(int id, const QString &year){ QSqlQuery query; query.prepare("update test_score set year = ? where id = ?"); query.addBindValue(year); query.addBindValue(id); return query.exec(); } bool ScoreModel::setStudentName(int id, const QString &studentName){ QSqlQuery query; query.prepare("update test_score set student_name = ? where id = ?"); query.addBindValue(studentName); query.addBindValue(id); return query.exec(); } bool ScoreModel::setStudentClass(int id,const QString &studentClass){ QSqlQuery query; query.prepare("update test_score set student_class = ? where id = ?"); query.addBindValue(studentClass); query.addBindValue(id); return query.exec(); } bool ScoreModel::setTestTime(int id,const QString &testTime){ QSqlQuery query; query.prepare("update test_score set test_time = ? where id = ?"); query.addBindValue(testTime); query.addBindValue(id); return query.exec(); } bool ScoreModel::setTestSubject(int id,const QString &testSubject){ QSqlQuery query; query.prepare("update test_score set test_subject = ? where id = ?"); query.addBindValue(testSubject); query.addBindValue(id); return query.exec(); } bool ScoreModel::setTestType(int id,const QString &testType){ QSqlQuery query; query.prepare("update test_score set test_type = ? where id = ?"); query.addBindValue(testType); query.addBindValue(id); return query.exec(); } bool ScoreModel::setTestScore(int id,const QString &testScore){ QSqlQuery query; query.prepare("update test_score set test_score = ? where id = ?"); query.addBindValue(testScore); query.addBindValue(id); return query.exec(); } bool ScoreModel::setStudyPeriod(int id,const QString &studyPeriod){ QSqlQuery query; query.prepare("update test_score set study_period = ? where id = ?"); query.addBindValue(studyPeriod); query.addBindValue(id); return query.exec(); } bool ScoreModel::setTestContent(int id,const QString &testContent){ QSqlQuery query; query.prepare("update test_score set test_content = ? where id = ?"); query.addBindValue(testContent); query.addBindValue(id); return query.exec(); } bool ScoreModel::setTeacherRemark(int id,const QString &teacherRemark){ QSqlQuery query; query.prepare("update test_score set teacher_remark = ? where id = ?"); query.addBindValue(teacherRemark); query.addBindValue(id); return query.exec(); } 的关键。关系R!

所以,我的问题是:

  • BCNF中的关系是否为R,为什么?
  • 确定BCNF中是否存在关系的正确流程是什么?

1 个答案:

答案 0 :(得分:1)

关于术语

你说:

  

我有决定因素a,b -> c,d

这是错误的热学。 a,b -> c,d是函数依赖(有时缩写为FD),其具有行列式 a,b(有时称为FD的左侧(LHS))和确定 c,d(有时称为FD的右手边,RHS)。使用此术语是因为属性a,b的值唯一地确定了属性c,d的值。

关于密钥

以下信息:

  

(a,b)是主键

当您拥有关于功能依赖关系的足够信息时,在规范化关系时,

可能无关紧要。从这些依赖项中,您可以计算哪些候选键:唯一确定关系的所有属性的属性集,以及您无法从维护此属性的任何属性中删除任何属性(换句话说,最小化)唯一确定关系的所有属性的属性集)。当您只有关于关系中包含的功能依赖关系的部分信息时,有关主键的信息可能是相关的,但在您的情况下,可以从功能依赖关系中获取有关所有(候选)键的信息。

例如,在您的示例中,有三个候选键:

1. a, b
2. a, c
3. a, d

您可以通过计算候选键属性的闭包来验证这一事实,以查看它是否包含所有属性。例如,让我们尝试计算a,d(称为a,d *)的关闭:

1. a,d * = a,d
2. a,d * = a,d,b  (since a, d -> b)
3. a,d * = a,d,b,c (since a, b -> c, d)

所以a,d是一个候选键(它也是一个超级键,即一组确定关系所有属性的属性)。

关于BCNF

BCNF有不同的定义。例如,使用您引用的第二个依赖项,所有三个依赖项都有一个决定因素,它是一个候选键(因此是一个超级键),因此该关系在BCNF中。