数据库设计三范式与实例

数据库设计三范式

    范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦,但是操作困难,因为需要联系多个表才能得到所需要数据,而
且范式越高性能就会越差。要权衡是否使用更高范式是比较麻烦的,一般在项目中,用得最多的也就是第三范式,个人认为使用到第三范式
也就足够了,性能好而且方便管理数据。

第一范式

定义:如果关系模式R的每个关系r的属性都是不可分的数据项,那么就称R是第一范式的模式。
简单的说,数据库表中的所有字段值都是不可分解的原子值,不可再分割,并且有意义。

错误示例:创建一个学生表

create table person(
    id varchar(18) primary key,
    name varchar(20) not null,
    info varchar(200)
);

insert into person(id,name,info)
 values("321645987945645","张三","出生日期:1980-1-1 家庭住址:中国陕西西安雁塔区电子称西部电子社区");

在这个学生表中,info字段包含太多的内容,info字段可以分割为以下信息:
生日、国籍、籍贯、城市、区域、详细地址

创建正确的person表应该如下:

create table person(
    id varchar(18) primary key,
    name varchar(20) not null,
    birthday date,
    guoji varchar(20),
    jiguan varchar(20),
    city varchar(20),
    area varchar(20),
    address varchar(50)
);

第二范式

    定义:如果关系模式R是1NF,且每个非主属性完全函数依赖于候选键,那么就称R是第二范式。
    简单的说,第二范式要满足以下的条件:首先要满足第一范式,其次每个非主属性要完全函数依赖与候选键,或者是主键。也就是说,
每个非主属性是由整个主键函数决定的,而不能由主键的一部分来决定。即,必须存在主键且唯一
    也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

如果所有情况都按第一范式设计就会有很多问题,例如:有一个学生成绩表,包含学号、姓名、课程、成绩

create table student(
   id int primary key,
   name varchar(20),
   course varchar(20),
   grade int
)

insert into student(id,name,course,grade) values(1001,"张三","Java",80);
insert into student(id,name,course,grade) values(1002,"张四","Java",80);
insert into student(id,name,course,grade) values(1003,"张五","C",80);
insert into student(id,name,course,grade) values(1004,"张六","c++",80);
以上表的设计会造成以下问题:
1、课程信息重复,一般会课程设置编号,但是编号在这里会重复出现。
2、如果有一个课程没有学生选修,这个课程的信息就不存在了。
3、修改课程信息时需要修改多条数据。

使用第二范式修改如下:

create table student(
   id int primary key,
   name varchar(20)
)
课程表作为一个实体表
create table course(
   id int primary key,
   name varchar(20)
)
选课表用来描述学生实体与课程实体之间的关系
create table sc(
   sid int,
   cid int,
   grade int
)
这里其实是一个多对多的关系,一个学生可以选择多门课程,一个课程可以被多个学生选修
    课程信息不会重复,课程编号也是唯一的
    即使没有学生选择的课程信息也不会丢失
    修改课程信息时只需要修改一条信息即可

第三范式

实际我使用第三范式最多。

    定义:如果关系模式R是2NF,且关系模式R(U,F)中的所有非主属性对任何候选关键字都不存在传递依赖,则称关系R是属于第三范式。  
    简单的说,第三范式要满足以下的条件:首先要满足第二范式,其次非主属性之间不存在函数依赖。由于满足了第二范式,表示每个
非主属性都函数依赖于主键。如果非主属性之间存在了函数依赖,就会存在传递依赖,这样就不满足第三范式。
    即,非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。

例如:学生表包含信息学号、姓名、所在学校、学校地址、学校电话

create table student(
    id int,
    name varchar(20)
)

create table school(
    id int,
    name varchar(20),
    address varchar(30),
    tel varchar(50)
)

create table ss(
   sid int,
   scid int
)

上边的例子则是描述的多对多的关系,这时一个学生可以在多个学校上学,一个学校有多个学生。

第三范式描述的是一个一对多的关系:
create table student(
    id int,
    name varchar(20),
    scid int
)

create table school(
    id int,
    name varchar(20),
    address varchar(30),
    tel varchar(50)
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值