orcale中3大范式总结

第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。

// 原文:绝大部分的表都满足第一范式的要求。但是下面这个表不符合。

修改:在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。

create table 学生(
学号 int,
学生信息 varchar(500)
);;

insert into 学生(学号,学生信息) values (1,'学生姓名:张三;年龄:18;专业:计算机;性别:男');
insert into 学生(学号,学生信息) values (2,'学生姓名:李四;年龄:22;专业:计算机;性别:男');

第二范式(2NF):若关系模式R符合第一范式,并且每一个非主属性都依赖于R的主键,则R属于第二范式。


第二范式是在第一范式的基础上建立起来的,即满足第二范式必须先满足第一范式。第二范式要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主键。


第二范式要求实体的属性完全依赖于主键。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。

比如说 有一个学生表,一个课程表,他们是多对多的关系。
如果我们这样设计:

create table 课程(
课程号 int primary,
课程名 varchar(20)
);

insert into 课程(课程号,课程名) values(1,'C语言');
insert into 课程(课程号,课程名) values(2,'数据结构');
insert into 课程(课程号,课程名) values(3,'操作系统');
insert into 课程(课程号,课程名) values(4,'数据库');
insert into 课程(课程号,课程名) values(5,'汇编语言');

create table 学生(
学号 int,
姓名 varchar(20),
课程号 int,
成绩 int
);

如果张三选择了4门课程 就意味着:
insert into 学生(学号,姓名,课程号,成绩) values(1,'张三',1,89);
insert into 学生(学号,姓名,课程号,成绩) values(1,'张三',2,77);
insert into 学生(学号,姓名,课程号,成绩) values(1,'张三',3,93);
insert into 学生(学号,姓名,课程号,成绩) values(1,'张三',4,65);

如果李四选了2门课程:
insert into 学生(学号,姓名,课程号) values(2,'李四',3,78);
insert into 学生(学号,姓名,课程号) values(2,'李四',4,68);

这样设计显然不合理,数据产生冗余。这样设计的话,学生表没法有主键,学生表的字段不是,也无法完全依赖主键。

解决方法:
//课程表
create table 课程(
课程号 int primary,
课程名 varchar(20)
);
insert into 课程(课程号,课程名) values(1,'C语言');
insert into 课程(课程号,课程名) values(2,'数据结构');
insert into 课程(课程号,课程名) values(3,'操作系统');
insert into 课程(课程号,课程名) values(4,'数据库');
insert into 课程(课程号,课程名) values(5,'汇编语言');

//学生表
create table 学生(
学号 int primary key,
姓名 varchar(20),
);

还要设计一个中间表---学生选课表:
create table 学生选课(
学号 int,
课程号 int,
成绩 int,
primary key(学号,课程号)
);
如果张三选择了4门课程 就意味着:
insert into 学生(学号,姓名) values(1,'张三');

insert into 学生选课(学号,课程号) values(1,1,67);
insert into 学生选课(学号,课程号) values(1,2,89);
insert into 学生选课(学号,课程号) values(1,3,74);
insert into 学生选课(学号,课程号) values(1,4,97);

如果李四选了2门课程:

insert into 学生(学号,姓名) values(2,'李四');

insert into 学生选课(学号,课程号) values(2,3,56);
insert into 学生选课(学号,课程号) values(2,4,87);

这样,学生表的非主字段完全依赖于学号,课程表的非主字段完全依赖与课程号,课程的成绩依赖于学号和课程号的组合。

所以,我们在设计在多对多关系中要有一个中间表。

第三范式(3NF):如果关系模式R属于第二范式,而且R的每一个非主属性(字段) 不会传递依赖于另外一个非主属性(字段),
也就是说,表的每一个属性都是由主键唯一确定的。

新增:第三范式要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

比如说有一个学生表:
create table 学生(
学号 int primary key,
姓名 varchar(20),
班级编号 int,
班主任 varchar(20)
);

因为主键只有一个,所以学生表满足第二范式。每一个学生都有属于某一个班级,所以要有班级编号;每一个学生都有一个班主任。
但是 班主任 依赖于 班级编号,而班级编号依赖于学号,所以产生了学号--班级编号--班主任 的传递依赖。

解决办法:
新建一个班级表:
create table 班级(
班级编号 int,
班级名称varchar(20),
班主任 varchar(20)
);

把学生表修改为:
create table 学生(
学号 int primary key,
姓名 varchar(20),
班级编号 int
);

这样就满足第三范式的要求了。

总结:我们建的大部分表都满足三范式的要求,三范式和我们学ORM,学Hibernate实际上是一样的。
数据库的表 对应着 Java中的类。从数据库角度上来看,三范式减少了冗余数据,从面向对象角度上看,三范式实现了对象的细粒度划分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值