Design4:数据库设计规范

当数据模型从概念层转到逻辑层时,需要进行规范化设计。要想设计一个结构合理的关系型数据库,至少需要满足1NF,2NF,3NF,即第一范式,第二范式,第三范式。

1,1NF(原子性)

1NF是最基本的,数据库表的每一列都是不可分割的原子数据项。

不可分割是相对而言的,依据实际需求来界定。

严格的说,某些TSQL的系统数据类型违反1NF,例如DateTime类型,包含了year,month,day,hour,minute,second,millisecond,但是我们更希望这些属性组合在一起,标识事情发生的具体时间点。

1NF提供了一种规范,优秀的设计模型,例如 姓名(full name)包含两部分,姓氏和名字,如果应用程序不会分别获取姓氏或名字,可以将full name视为原子数据项,但是,如果程序需要获取姓氏或名字,那么将full name拆分,划分为两列(surname 和 name)是更好的设计模型。

2,2NF(属性完全依赖于主键

表中的所有列,都必须完全依赖于主键,由主键唯一标识所有属性列,对于不完全依赖于主键的列,会出现数据冗余,需要拆分成表。

例如以下是个成绩表,各个字段的含义是 Cid(course id),Cname(course name),stuid(student id),stuname(student name),主键是cid和stuid,但是cname,stuname,professionid和professionname并不完全依赖于主键,cname完全依赖于CID,stuname,professionid和professionname完全依赖于stuid。

按照2NF的要求,将依赖于主键属性的所有属性集中到一个表中,上图数据能拆分成三个表,dbo.student,dbo.course,dbo.score,消除数据的冗余。

表是属性的集合,一个表是一个实体,例如student表,有学号,name,profession属性,学号是主键属性,能唯一标识一个student实体,能够根据学号唯一确定一位学生的name,profession属性。

create table dbo.student
(
stuid int not null primary key,
stuname varchar(100) not null,
professionid int ,
professionname varchar(100)
)

create table dbo.course
(
cid int not null primary key,
cname varchar(100) not null
)

create table dbo.score
(
cid int not null foreign key references dbo.course(cid),
stuid int not null foreign key references dbo.student(stuid),
score int null
primary key(cid,stuid)
)

3,3NF(属性不能传递依赖于主属性,即属性不依赖于其它非主键属性)

如果某一属性A依赖于非主键属性B,而非主键属性B依赖于主键pk,那么属性A就是间接依赖于主键pk,这被称作传递依赖于主属性。

例如,ProfessioName 是专业名称,每一个专业的名称是唯一的,跟学生没有关系,ProfessioName依赖于ProfessionID,而ProfessionID完全依赖于stuid,因为student表的属性是由stuid唯一标识的,所以ProfessioName传递依赖于stuid。

对传递依赖进行范化,需要将传递依赖的属性拆分成表,例如

create table dbo.profession
(
    professionid int not null primary key,
    professionname varchar(100)
)
create table dbo.student
(
    stuid int not null primary key,
    stuname varchar(100) not null,
    professionid int foreign key references dbo.profession(professionid)
)

 

posted @ 2015-06-18 19:08  悦光阴  阅读(626)  评论(0编辑  收藏  举报