数据库架构
总结一下,数据库有哪些方面的知识点。
-
数据库的架构部分:这部分主要考察大家对于数据库有没有一个整体的了解
-
索引部分:这是最重点最常考的
-
锁部分
-
语法部分:这是我们工作中经常用到的
-
数据库的纯理论部分 - 如范式理论
范式理论:
范式一:列不可代分
范式二:标主键
范式三:去除传递依赖
1NF:建表时要保证列的原子性(即不可分割性);打个比方:
电话这个字段有可能是座机,也有可能是手机,具有可分割性,所以不符合1NF;应该改成:
这样就符合列的不可分割性,即第一范式;
**2NF:**第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。
是不是发现看不懂?没关系,可以看一个简单的例子:
如果一个客户定了多个房间,那么那么相当于后面的联系人、联系人电话、身份证号这三个字段就会重复出现在每一行数据中,造成数据的冗余,不符合第二范式(2NF);所以第二范式要符合所有字段要和主键有直接的依赖关系,不然会造成数据的冗余;应该改成一对多的形式,这样就能解决冗余的问题:
订单表:
客户表:
**3NF:**第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。
再来看个简单的例子:
现在有个Student表,如果把表设计成这个样子的话,那么所在院校、院校地址、院校电话这三个字段的信息就会有大量的重复,不符合第三范式(3NF);
应该改成这个样子:
学生表:
学院表:
如何设计一个关系型数据库?
遇到这类问题往往让人不知所措,因为要说的东西太多了。其实不必慌张,万变不离其中设计一个数据库,就像设计一款软件差不多。也是将其分解成很多模块,很考验我们的模块换分能力,以及对数据库的理解。
记一个东西的最佳方式,便是站在设计者的角度去设计它。所以只要我们能回答出来,也说明了我们对数据库的基本功能以及作用有了一个全面的了解
我们先来了解一下数据库的基本模块,以便来加深对数据库的认识,设计及模块划分那要开发一个数据库咱们要开发什么模块?首先数据库的最主要功能是什么?就是存储我们的数据,因此他会有一个存储模块来负责存储我们的数据存储模块类似我们的OS文件系统,将数据最终持久化,存入磁盘中如存入机械硬盘或者SSD固态硬盘
此时光有储存是不行的,我们还需组织并且用到这些数据,因此咋们需要有程序的实例,用逻辑结构来映射出物理结构来,并且在程序中提供获取并且管理数据的方式还有必要的问题追踪机制
接下来,咋们来细分一下程序的模块。
首先我们需要对数据的格式以及文件的分隔,进行统一的管理即把物理数据通过逻辑的形式给组织和表示出来,于是便涉及到了咋们数据库的存储管理模块。咋们这里插入个题外话我们需要怎样优化存储效能,我们都知道处理数据不可能在磁盘上做,肯定是要程序加载到程序空间所在的内存里面去做。而磁盘IO速率往往是程序执行速率的瓶颈,大家可以看到咋们的机械硬盘它通过马达的驱动盘面的转动以及磁头的移动来查找数据,这样查找的速率呢。远差于内存的查找效率,即便是通过电流驱动的固态硬盘虽然拥有比机械硬盘更快的IO速度,但是根内存比起来呢也不是同一个量级的,因此为了执行效率咋们需要尽可能的减少IO,就这个存储管理功能而言如果安装逐行去查找并返回那么频繁的IO呢。会让咋们的数据库慢如蜗牛因为一次IO读取一条数据和多条数据并没有多大的区别,所以我们可以一次性地读取多行以提升IO的效能,所以行就失去了它的意义。那么所以数据库把存储单位用快或者页来表示,每个块或者页中会存放多行数据 这样读取的时候可以将多个块一起加载进内存当中。
ok 回到正题。作为一款很追求性能的软件,我们没有好好利用内存,因此为了更快更好的优化我们的程序。我们应该想到做项目的时候呢,的一种普遍做法就是利用缓存机制,把取出来的数据块存进缓存里,下次需要的时候直接从内存返回,而不需要发生IO,这里需要补充的是刚才咋们说到的一次性加载多个模块或者页,这些块里内数据行相当一部分并不是我们本次查询 需要的行,但是呢根据一旦某行数据被访问了,那么它周围的数据内也是极有可能被访问的经验,缓存的非本次数据也能起到优化访问效率的作用。那个块里面 有 A,B,C 三条数据我们只需要A的数据,那么B,C它们也会加载到内存当中了 。那么安照经验来说下次B,C被访问到的几率是非常大的,那也就是他也能够提升了我们访问的性能,关于如何管理缓存呢,有很多的方法如LRU等。也不能说哪些方法最好,某些方法适用于某个具体的场景。
接下来,我们还需要提供给外界指令来操作我们的数据库可读的SQL语言,那么呢我们就需要一个SQL的解析模块将SQL编译解析转换成机器可识别的指令,那么我们需要进一步提升SQL执行效率该怎么办?老方法还是将我们的额SQL缓存到我们的缓存里,那编译好的SQL呢。方便下次来了直接就进行解析就可以了。大家可以注意到设计咱们的程序呢要先实现咋们的功能,接着再考虑优化。周而复始,这里还需要考虑一点我们的缓存呢不宜过大且算法里呢要有淘汰机制。淘汰掉一下之后不常用的数据,之外咋们做的SQL操作 要记录下来方便我们做我们数据库的主从同步,或者灾难恢复,因此我们就需要有日志管理模块,去对我们的操作记录做记录。如bigLog。
我们还需要提供给用户管理数据的私密空间即权限划分,通俗来讲就是让老板看到员工的数据而员工只能够看到自己该看到的数据 权限划分是我们DBA做的事情,通常不需要我们过多关心。
设计系统的时候不仅要考虑正常的功能还要考虑异常的情况,那怎么处理异常的情况呢?那就需要引入异常机制就是容灾机制。当我们的数据库挂了该如何恢复,恢复到什么程度,这些都需要设计
接下来要进一步的提升查询数据的速度,以及呢要让我们数据库呢支持并发咋们还需要引入最能突出数据库特点的两个模块 索引管理 和 锁模块。这两个模块既是我们接下来要讲解的重点,也是是数据库知识的重中之重。
ok,那来回答刚才的问题是不是简单多了。要设计一个关系型数据库。首先咋们需要将其划分成两大部分一个是存储部分,该部分类似于一个文件系统来将数据持久化到存储设备当中 ,那光有存储是不行的咋们还需要有程序实例模块来对存储进行逻辑上的管理,而程序的实例部分将包含数据的物理关系转换成物理存储关系的存储模块。优化执行效率的缓存模块。将SQL语句进行解析的SQL解析模块,记录操作的日志管理模块。进行多用户管理的权限划分模块。灾难恢复模块。优化数据查询效率的索引模块以及使得数据库支持并发操作的锁模块。主要就是分为这8个模块。
讲到这里不知大家是否体会到,数据库的开发跟我们做的项目一样,考虑设计的模块都非常的类似的。其架构堪称经典所以对我们的程序开发,很有借鉴的意义。
得数据库支持并发操作的锁模块。主要就是分为这8个模块。
讲到这里不知大家是否体会到,数据库的开发跟我们做的项目一样,考虑设计的模块都非常的类似的。其架构堪称经典所以对我们的程序开发,很有借鉴的意义。