为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式数据库范式实际上非常重要,但是从开发来看,如果真的按照要求去做,则查询语句会变得非常复杂.
创建一个用户表:
create table person (
pid number(4) primary key not null,
name varchar2(50),
info varchar2(200)
)
insert
into person(pid,name,info)
values(111,'zhangsan','1983年11月23号出生,住在北京西胡同')
insert
into person(pid,name,info)
values(112,'messixi','1985年12月30号出生,住在北京八大胡同')
实际上可以发现人员信息由以下几部分组成
生日:1985年11月23号
省市:北京
详细地址:西胡同
会发现该数据有一下问题
info字段信息可以再分,要求字段不可再分,再次设计表结构,表结构如下
create table person (
pid number(4) primary key not null,
name varchar2(50),
birthday varchar2(50),
area varchar2(50),
subarea varchar2(50),
address varchar2(50)
)
这样每个字段就不可再分。
这样就满足了第一范式:
要保证每个列的有意义,且不可再分,每一列都是不可分割的原子数据项。
但是所有操作都满足第一范式也会遇到如下问题:
创建一张学生学课表,满足第一范式:
create table selectcourse(
stuno varchar2(50),
stuname varchar2(50),
stuage number(4),
cname varchar2(50),
grade varchar2(50),
credit number(4)
)
insert into selectcourse values('s001','陈田',20,'java',89,3)
insert into selectcourse values('s002','赵琦',21,'java',68,3)
insert into selectcourse values('s003','王六',20,'java',70,3)
插入以上三条数据,会发现问题
1所有课程信息冗余
2如果学生没有选择该课程,则课程会从学校彻底消失
3课程中本身也应该包含一个课程编号,但是按照第一范式设计,课程编号肯定重复。
4如果要更改课程信息,则要更改许多条记录
所以该表设计应该满足第二范式:
数据库表中不存在非关键字段对一候选关键字段的部分函数依赖,也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中
既由以前的创建一张表,改为创建三张表
学生表
create table student(
stuno varchar2(50) primary key,
stuname varchar2(50),
stuage number(4)
)
课程表
create table course(
cid varchar2(50) primary key,
cname varchar2(50),
credit number(4)
)
学生选课关系表
create table selectcourse(
stuno varchar2(50),
cid varchar2(50),
grade number(4)
有外键关联,且stuno和cid是联合主键
)
insert into student values('s001','大罗',20)insert into student values('s002','小罗',19)
insert into student values('s003','c罗',18)
insert into course values('ca','java',3)
insert into course values('cb','oracle',5)
insert into selectcourse values('s001','ca',89)
insert into selectcourse values('s002','ca',77)
insert into selectcourse values('s003','ca',67)
发现解决前述的那些问题,完成了一个多对多的关系。
第三范式:
在第一范式基础上,任何非主属性不依赖于其它非主属性,即确保数据表中的每一列数据都和主键直接相关,而不能间接相关
如现在要求设计一张学生表,肯定不能使用第一范式,如果现在使用第二范式
1 学生表
create table student(
stuno varchar2(50) primary key,
stuname varchar2(50),
stuage number(4)
)
2 学院表
create table collage(
cid varchar2(50) primary key,
cname varchar2(50),
cadress varchar2(50)
)
3 学生学院关系表
create table selectcourse(
stuno varchar2(50),
cid varchar2(50),
有外键关联,且stuno和cid是联合主键
)
按照这种设计,一个学生可以同时在多个学院上课,同时多个学院会有同一个学生.此时第二范式不满足,应该一个学院只包多个学生,一个学生只能属于一个学院,更改此设计
1 学生表
create table student(
stuno varchar2(50) primary key,
stuname varchar2(50),
stuage number(4),
cid varchar2(50) 外键
)
2 学院表
create table collage(
cid varchar2(50) primary key,
cname varchar2(50),
cadress varchar2(50)
)
此时是学院学生一对多关系。
第二范式满足多对多关联
第三范式满足一对多关联
总结:三范式只是一种参考,数据库唯一原则,数据库关联查询越少越好,sql语句复杂越低越好.