关于Oracle数据库的学习记录:
五十一、数据库设计范式(第二范式)
2.第二范式(多对多关系)
“数据表之中不存在非关键字段对任意候选关键字端的部分函数依赖”
首先来对这个概念进行一个解释,两个关键字:函数、函数依赖
所谓函数关系,简单点理解,就是数据表之中的两个列之间不要存在有数学关系
CREATE TABLE orders(
unitprice NUMEBR,
quantity NUMBER,
allprice NUMBER
);
这个时候设计的表中存在以下的关系:allprice=unitprice*quantity
依赖,指的是通过某几个字段可以及成功的推演出唯一的一个字段
例如:
电影名称 年份 导演 演员 出版商
甲方乙方 1998 冯小刚 葛优 、刘培根 A公司
非诚勿扰 2008 冯小刚 葛优、舒淇 华谊兄弟
让子弹飞 2009 姜文 葛优 B公司
现在给出的数据里面:
(电影、年份、出版商)=导演
(年份、电影)不等于演员
实际上就算把上面的概念都搞明白了,也还是不明白第二范式,那么下面通过一个实例来说明
现在要求设计如下操作:设计一个学生选课数据表,每个学生针对于每门课程可以有一个成绩,每个课程有学分,首先采用第一设计范式来设计
CREATE TABLE student_course(
stuid NUMBER,
sname VARCHAR2(50),
ctitle VARCHAR2(50),
credit NUMBER,
score NUMBER,
CONSTRAINT pk_stuid PRIMARY KEY(stuid)
);
这个设计现在已经符合第一设计范式,如果真这样设计了会存在哪些问题?
范例:增加一些数据来观察
INSERT INTO student_course VALUES(1,'张三','HTML',2,80);
INSERT INTO student_course VALUES(2,'李四','Oracle',3,90);
INSERT INTO student_course VALUES(3,'王五','Oracle',3,91);
INSERT INTO student_course VALUES(1,'张三','Java',3,89);
存在问题如下:
**无法设计一个合适的字段作为主键
**课程信息重复,那么如果更新一个课程信息则需要更新N行记录
**如果说现在有一门课程一直没人报名参加,那么这个课程信息就彻底取消了
CREATE TABLE student(
stuid NUMBER,
sname VARCHAR2(50),
CONSTRAINT pk_stuid PRIMARY KEY(stuid)
);
CREATE TABLE course(
cid NUMBER,
ctitle VARCHAR2(50),
credit NUMBER,
CONSTRAINT pk_cid PRIMARY KEY(cid)
);
CREATE TABLE student_course(
stuid NUMBER REFERENCES student(stuid) ON DELETE CASCADE,
cid NUMBER REFERENCES course(cid) ON DELETE CASCADE,
score NUMBER
);
INSERT INTO student VALUES(1,'张三');
INSERT INTO student VALUES(2,'李四');
INSERT INTO student VALUES(3,'王五');
INSERT INTO course VALUES(10,'马克思主义哲学');
INSERT INTO course VALUES(11,'Java');
INSERT INTO course VALUES(12,'Oracle');
INSERT INTO student_course VALUES(1,10,90);
INSERT INTO student_course VALUES(1,11,89);
INSERT INTO student_course VALUES(2,11,99);
INSERT INTO student_course VALUES(3,12,91);
所有的数据都可以进行各自的实体表的维护