数据库结构的优化,要贯穿数据库结构设计的始终,所以我们先要了解一下,数据库设计的步骤都包括哪些,简单来说呢,
数据库设计的步骤,是随着产品需求的不断变更,而循环往复的,主要是由以下4个步骤来组成的,首先数据库的设计呢,
根本上来说是软件系统的设计,所以和所有的软件工程是一样的,我们要对产品的实际需求进行分析,形成需求分析
文档,这一步是非常重要的,是否能够设计出符合实际需求的高效的数据库需求,很多存在数据库性能的数据库呢,
都是由于一开始,没有做好需求分析,所造成的,可以想象一下,如果我们的需求分析呢,做的不全面,就一定会造成产品
上线后,频繁的修改数据库结构,这样的问题,这样就会变成原本很高效的数据库呢,在多次修改后,就变成难以使用了,
严重的情况下呢,上面提到的数据冗余啊,维护异常,这样的问题,在需求分析阶段呢,主要工作就是要全面了解产品设计
对数据库设计的存储需求,调查,收集,和分析所要开发的产品,在数据库中,存储需求,以及数据的处理需求,而数据的
安全性和完整性,数据存储需求显而易见,是指数据库要存储什么样的数据,对于数据会有什么样的特点,而数据处理
需求呢,是指我们如何对数据库进行读取,或者修改以完成产品的功能,以及对数据处理的响应时间又什么样的要求,
处理的方式是批量处理呢,另外就是对数据的安全性和完整性,有什么样的需求,还包括数据的生命周期等信息,以上就是我们
要求的需求分析阶段所要完成的工作,说起来很简单,但是从事过实际工作的人都知道,需求分析阶段,有时是很难的一个阶段,
因为需求提出的业务人员呢,通常对技术并不了解,所以有时候很难知道技术方案是什么,而技术人员对业务可能不太了解,
所以工作起来很费劲,所以这就要求我们在这一阶段呢,多做很多的工作,要反复的跟业务人员沟通,确认需求的真正内容
是什么,如果我们顺利的完成了需求分析,我们就可以进入数据库的第二个阶段
也就是逻辑设计阶段,在这个阶段我们不用关心我们所使用的是什么数据库,什么存储引擎,等于在这个阶段呢,
要做的就是搞清楚,数据实体之间的逻辑关系,要解决数据冗余和数据维护异常的话,重点是在这个阶段,所以这个阶段呢,
我们想要做的工作呢,不但重要,而且会直接影响以后的数据处理和数据存储方式,解决了数据冗余和数据维护异常,且高效的
数据库逻辑设计呢,并不容易,不过好在这个阶段呢,我们有些秘籍可以参考,这些秘籍呢,就是所谓的数据库的三大范式,也提到过,
按照要求来进行数据库的设计呢,可以最大程度的解决数据库的冗余,和维护异常,这样的问题,对于什么是数据库的三大范式呢,
相信大家多少有些了解,如果还不了解的话,也不用着急,我们下面马上就回提到,完成了第二阶段的工作呢,现在我们就要考虑我们的
业务所使用的数据库类型
这个就代表了我们要进入物理设计阶段,在这个阶段呢,我们要做的就是要根据我们使用数据库的特点,进行表结构的设计,
目前我们使用数据库的种类呢,有很多,常见的关系型数据库有ORALCE,SQLServer,MYSQL,等等,而非关系型数据库呢,选择的
就更多了,比如大家知道的mongo,redis,hadoop等等,不过说实话,大多数情况下呢,由于开发人员绝对使用什么样的数据库的
情况并不多,特别是回到我们课程中来说,我们只能使用MYSQL,不过对于MYSQL来说呢,有很多的需要我们选择的东西,比如使用
什么样的存储引擎,表中的类使用什么样的数据类型,这个都是要在物理设计阶段来决定,特别是存储引擎和列的数据类型的选择呢,
对数据库新能的影响是很大的,存储引擎已经反复提到了多次了,这里还是要再强调一下,大家使用innodb存储引擎,而表中对于
数据类型是如何选择的呢,放到下面来进行讲解,完成了数据库的物理设计,实际上呢我们就已经完成了现阶段数据库设计的工作了,
不过后续的工作中呢,我们还要不断地对数据库结构进行调整,维护,和优化
以及数据字典维护这种工作,最主要的可能就是对索引进行优化和维护了,这些内容可能在后面的内容呢,都会
有所涉及,所以呢还是把具体的内容,到后面来说,前面提到了很多次数据库设计的范式,下面我们就给大家来讲一下
什么是数据库设计范式,所谓的数据库设计范式呢,说白了就是我们在进行数据库设计时,所遵循的一些规范,只要我们
按照规范的要求呢进行设计,就可以设计出没有数据冗余,和维护异常的数据库的结构,当然了,关于数据库设计的规范
有很多,不过通常来说呢,数据库规范又称之为数据库三大范式,当然呢还存在其他的范式,但是在一般情况下,你只要做到
满足,前三个范式的要求就可以设计出,符合我们使用的数据库了,大家要注意,这里呢,这里只说符合需求的设计,并不是说
性能最好的设计,是因为呢,我们也不能完全按照范式呢,来进行设计,因为我们在设计数据库时呢,还要考虑业务的实际使用的情况,
所以有时候也要做一些,违反范式的设计,不过我们还是先来看一看,数据库的三大范式,首先我们先来看第一大范式,第一范式
呢,最基本的数据库设计范式,基本上所有数据库设计呢,都是符合第一范式要求的,符合第一范式设计的表呢,有以下的特点,
首先,数据库中表中所有字段,都具有单一的属性,也就是说,不能再进行分解,并且这些单一属性的列呢,是由基本的数据类型,
比如整形啊,浮点型啊,字符型啊,这些数据类型所构成的,最后一点就更简单了,就是我们所设计出来的表呢,都应该是简单的
二维表,以上三点呢,基本上是所有数据库设计,都可以满足的,然后我们演示来说吧,我们可以看一下
在我们的selectcourse选课表中,这张表就是符合第一范式的表,因为完全符合以下三点的要求,首先,
这个表每一列都是不可拆分的,其次呢,这个表中所有列呢都是由最基本的数据类型所构成的,最后呢,这张表是
一张二维表,第一范式的要求也说过了,这张表还是存在数据冗余,和数据维护异常这样的问题,所以只满足第一范式
的设计呢,还是不够的,所以我们要继续看看第二范式,数据库设计的第二范式,是在第一范式基础之上定义的,也就是
说,符合第二范式要求的表呢,首先要满足第一范式的要求,第二范式呢,要求一个表中,只具有一个业务主键,也就是说
符合第二范式的表中呢,不能存在非主键列,只对部分主键的依赖关系,当然呢非主键列呢,只对部分主键有依赖的这种
情况呢,只能出现主键是复合主键的时候,如果我们的主键是单一主键,那么这个表的设计呢,就一定是满足第二范式要求的,
我们还是以学习讲课表为例,来为大家演示一下,如何改进才能把这个表设计的符合第二范式要求
首先我们来看目前我们的selectcourse表的主键是一个复合主键
show create table selectcourse;
大家可以看到,这里是学号,和课程名两列组成的复合主键,所以是不满足第二范式要求的,我们再看学分这一列,
实际上只和课程名称是有关系的,所以这样看来,就出现上面所说的,非主键列值,和部分主键存在依赖关系,所以我们
说这个表是不符合第二范式要求的,所以我们可以对这个表进行拆分,使其符合第二范式的要求,我们这里可以把这张表
拆分为三张表,分别是学生表,课程表,和学生课程选课关系表,可以看到,selectcourse拆分为三张表,包括学生表
学生表
show create table student\G
课程表,这就是拆分后的两种表,大家可以看到
两个表都只有一个主键了,所以这两张表一定是符合第二范式要求的,而第三张表呢,selectcourse存在非主键,
所以也是符合第二范式要求的,我们现在来看看第三张表,这就是第三张表
show create table studycourse\G
学生和课程中的关系表,那么我们还来看看第三张表是否还存在数据冗余,和维护异常这种情况,我们可以看到,
对于course,和studycourse表已经解决数据冗余,维护异常的问题,如果我们增加新的课程,只要在course表中进行
增加,相应的记录就可以了,不用去管是否有学生来选了这门课程,但是对于study表存在一个问题,我们来看看study
表的具体内容是什么
select * from study;
大家可以看到,学院名称和学院电话,数据冗余的问题,现在这张表已经符合第二范式的需求了,所以我们就要继续
来看这张表符不符合第三范式的要求,那么所谓的第三范式呢,是指每一个非主的属性,不可部分依赖于,也不可传递依赖于
业务主键,也就是在第二范式的基础上,消除了非主属性对主键的传递依赖,这个定义并不是很容易理解,所以我们还是来
看一下实际的表,这样大家就可以明白,什么叫传递依赖关系了
前面在介绍第二范式的时候呢,我们已经说过了,selectcourse表拆分成三张表以后,课程表和学生选课关系表呢,
这两张表就已经解决数据冗余和数据维护异常问题,现在唯一存在数据冗余和数据维护异常的呢,就是学生表,所以我们看看
第三范式是否可以解决学生信息表所存在的一些问题,我们先来看学生信息表的表结构,上面我们已经查询过了,我们可以看到,
学生信息表中有一个组件是学号
所以这是符合第二范式的,但是同时这张表中呢存在上面的依赖关系,学号可以确定学生所在的学院,而学院的
地址呢,与学院又有依赖关系,那学院与学院地址呢对于学号来说,它是具有传递的依赖关系的,所以说学生信息表呢,
是不符合第三范式的要求,那么我们现在就要对这张表进行改造,符合第三范式的要求,所以依然要把这张表进行拆分,
这里我们就把学生信息表拆分成两张表,分别是学生信息表,与学院信息表,那么下面我们来看一看这两张表的表结构,
首先来看一下学生信息表的表结构,我们叫study_info,大家看,这张表我已经建好了,还没有建立,那我们自己建立吧,
我们要建立一个学生信息表,原来学生信息表的一部分信息,首先我们还是以学号来作为他的主键,下面我们还要包括学生
姓名这一列,这些都是在原来学生信息表存在的列,接下来就是生日列,以及学院名称,主键同样是学号,这里就完成学生信息
表的建立
create table study_inf(study_no int not null,study_name varchar(10),birth_date timstamp,
school_name varchar(20)),primary key(study_no);
同时我们还会把原来的学生信息表再拆分出一个表来,学院信息表,这里面的列比较简单,首先有学院的名称,
以及学院的电话,他的主键是学院名称,大家可以看到,经过这样拆分之后呢
create table school_inf(school_name varchar(20) not null,school_tel varchar(10),
primary key(school_name));
desc study_inf;
符合第三范式的需求了
desc school_inf;
首先这两张表呢都不会存在数据冗余,和数据维护异常,同时也就是说,我们对这些表应用到第三范式呢,
就基本上解决了数据冗余和数据维护异常的问题,通过以上的说明呢,相信大家对数据库三大范式有了一定的
认识,我们在数据库逻辑设计阶段呢,主要解决的问题呢,是要消除表中所存在的数据冗余和数据维护异常的问题,
为了让大家对数据库的设计有一定程度的了解,我们就一个实际的需求为例呢,来一起完成这个需求的逻辑设计和我
物理设计,这样大家呢对数据库表设计阶段就更加的清楚了