我有一个R(a,b,c,d)
关系,其中(a,b)
是主键,所以我有决定因素a,b -> c,d
。
除此之外,我还有以下决定因素:a,c -> b,d
和a,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!
所以,我的问题是:
答案 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中。