最近做了一个小项目完整的数据库设计,想总结一些设计上的所得,希望大家多多指教。
有时一个项目,普通程序员一般不会去接触数据库设计,一般都有专业的DBA或是老程序员去设计,下面是我推测的几点可能原因:
1:新手对项目了解不深,正好这是老鸟的长处。
2:新手对局部的关注往往大于整体,很难考虑的特别周全。
3:数据库设计的好坏在某种程度上直接影响项目的复杂度以及性能。
第一:我们要知道什么是范式,为什么说到数据库设计总要提到一个名词:范式。范式:符合某一种级别的关系模式的集合。设计数据库必须遵循一定的规则,在关系数据库中,这种规则就是范式。
第二:范式的分类。关系数据库中的关系必须满足一定的要求,目前关系数据库有六种范式:第一范式、第二范式、第三范式、第四范式、第五范式和第六范式。满足最低要求的是第一范式,其余范式以次类推。这么多的分类并不一定要求全部满足,平时我们通常是达到第三范式就行。
第三:范式的作用?
1:优点:是将其转化为一些表的过程,这种方法可以使从数据库得到的结果更加明确。
2:缺点:可能使数据库产生重复数据,从而导致创建多余的表。
3:是在识别数据库中的数据元素、关系,以及定义所需的表和各表中的项目这些初始工作之后的一个细化的过程。
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)4:设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,也不会发生插入、删除和更新操作异常。反之则给编程人员制造麻烦,可能存储了大量不需要的冗余信息。
下面来简单介绍下前三种范式:
一:第一范式。是对关系模式的基本要求,不满足第一范式的数据库就不是关系数据库。 所谓第一范是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。 例如有一张存储文件的表,正确应该是这样:可以看到这个表包含了好几个列,如果我们把这些信息都放在一列里面那么就不满足上面定义的1NF了。
create table Regulations (
ID int identity,
Title nvarchar(200) null,
FileAddress varchar(255) null,
OpenDate datetime null,
TypeID int null,
PostDate datetime null,
constraint PK_REGULATIONS primary key (ID)
)
二:第二范式:在第一范式的基础上建立起来的。要求数据库表中的每个实例或行必须可以被惟一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。像上面的Regulations的ID列就是一个身份标识列(identity)。
三:第三范式:要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如:上面有了一个文件表 Regulations,如果这个表是存储的主文件,它相应的还有n个附件信息的话,我们就需要创建另外一张附件表来存储附件。两表如何联系起来呢,我们可以把主文件表的主键随同附件信息做为一条记录插入到附件表中,这里插入的主文件表信息中只包含了主键ID,并没有插入其它信息,这种关系就满足了第三范式要求。
create table Attachment (
ID int identity,
FileID int null,//主文件主键ID
Address varchar(255) null,
Title nvarchar(200) null,
constraint PK_ATTACHMENT primary key (ID)
)
最后来总结了我这个项目中的具体应用:
第一:启用数据字典理念来提高开发效率。什么是数据字典这里我不多说,大家不知道的可以网上搜索下。在一个项目中有时会遇到非常多的选项,就是供表单选择某些小数据项的内容,请看下面的图:
每一个模块在插入记录时都或多或少有这样的选项,如果每一张表都建一个对应的选项表的话,维护进来工作量相当大,所有可以把这些小数据量的选项存储到一张表,数据字典表如下:
下面是数据字典的数据展示图:
第二:对数据库表字段数据类型的设置有了进一步认识。
1:SQL有一种特殊的数据类型;Unicode 数据类型,包括 Nchar,Nvarchar 和Ntext 传统的非 Unicode 数据类型允许使用由特定字符集定义的字符。使用 Unicode 数据类型,列中可以存储任何由Unicode 标准定义的字符。在 Unicode 标准中,包括了以各种字符集定义的全部字符。使用Unicode数据类型,所占用的空间是使用非 Unicode 数据类型的两倍。当列的长度变化时,应该使用Nvarchar 字符类型。当列的长度固定不变时,应该使用 Nchar 字符类型。我们在表单验证时,用户有时会输入英文和中文混合文字,为了验证方便,可以将这种情况时的字段设置成Unicode 。
2:对于非Unicode 数据,尽量选择相对应的类型,例如手机号码一般都是数字组成,且长度基本固定,设置成char(15)就行,email设置成varchar(100)就行。
第三:如何灵活利用一对多关系。一对多的关系非常常见,但如果加以灵活应用有时效果更佳。
例如,上面的图中有一个了解管道的选项,它和对应的主表是一对多的关系,如果这个选项在不同的模块中出现,我们是否需要为每个主表建立一个一对多关系呢?我选择做一个中间关系表。我们可以把所有模块中包含了了解管道选项的主表与这个中间关系表联系起来,这样就只用维护这一个关系表就行了,节约不少时间。