数据库系统概念--(范式,存储,查询,事务,引擎)

来源:互联网 发布:淘宝芝士年糕哪家好吃 编辑:程序博客网 时间:2024/05/02 18:49

1.总览

  • 范式(1NF, 2NF ,3NF) 和各自的作用
  • 设计一个数据库
  • 数据存储和查询
  • 事务管理
  • mysql中的存储引擎 myisam 和 innoDB
  • 分布式数据库

2.范式

什么是范式? 
一个场景给你 怎么来把表设计好,  初学者一般都会把所有的东西都堆在一个表里面. 
在一个表有什么问题? 这个一般都会有修改困难,(修改 自己的名字,需要全部都要修改)  插入困难,删除困难

那么为了解决这些问题就出现了范式 .
范式越高. 数据的冗余程度越低, 同样的 修改困难,插入困难 ,删除困难,等等这些问题就越少.
规范化的过程: 将大的表通过投影的方法,切分成很多张小的表. 通过这些表中的 公共的关联列, 通过自然连接 还原出大的表.

  • 第一范式(1NF):  所有属性(列)均为简单属性, 每个属性都是不可再分的.
  • 第二范式(2NF):  消除部分 子函数依赖.
  • 第三范式(3NF):  属性不依赖于其它非主属性。不存在传递函数依赖
第一范式很容易理解,简单来说就是每个表里面的属性都是要是不可再分的, 也不能存在一个列里面有多个属性那种. 
第二范式, 是建立在第一范式上面, 同时要消除部分子函数依赖,子函数依赖? 是什么?(就是关键词,比如码 ,码组合中 各自可以对应 不同的属性)
比如:
      (学号, 课程名称) → (姓名, 年龄, 成绩, 学分) 
   这个数据库表不满足第二范式,因为存在如下决定关系: 
   (课程名称) → (学分) 
   (学号) → (姓名, 年龄) 

这些都是子函数依赖. 如果不满足第二范式的时候就可能出现一些列的问题.
  •       数据冗余: 同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。 
  •    更新异常: 若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。 
  •    插入异常: 假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。 
  •    删除异常: 假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。 
第三范式: 在第三范式中不应该存在
        关键字段 → 非关键字段x → 非关键字段y 
        不满足第三范式也会存在数据冗余、更新异常、插入异常和删除异常的情况 
 


3.设计一个数据库

软件项目开发周期
  • 需求分析阶段:分析客户的业务和数据处理需求;
  • 概要设计阶段:设计数据库的E-R模型图,确认需求信息的正确和完整;
  • 详细设计阶段:将E-R图转换为多张表,进行逻辑设计,并应用数据库设计的三大范式进行审核;
  • 代码编写阶段:选择具体数据库进行物理实现,并编写代码实现前端应用;
  • 软件测试阶段:……
  • 安装部署:……

设计数据库

  • 在需求分析阶段,设计数据库的一般步骤为:
    –         收集信息
    –         标识对象
    –         标识每个对象的属性
    –         标识对象之间的关系
  • 在概要设计阶段和详细设计阶段,设计数据库的步骤为:
    –         绘制E-R图
    –         将E-R图转换为表格
    –         应用三大范式规范化表格

数据规范化

  • 仅有好的RDBMS并不足以避免数据冗余,必须在数据库的设计中创建好的表结构。表设计后,很可能结构不合理,出现数据重复保存,简称数据的冗余,这对数据的增删改查带来很多后患,所以我们需要审核是否合理,就像施工图设计后,还需要其他机构进行审核图纸是否设计合理一样。
  • 如何审核呢?需要一些有关数据库设计的理论指导规则,这些规则业界简称数据库的范式。Dr E.F.codd 最初定义了规范化的三个级别,范式是具有最小冗余的表结构。这些范式是:
    第一范式(1st NF -First  Normal Fromate)
    第二范式(2nd NF-Second  Normal Fromate)
    第三范式(3rd NF- Third  Normal Fromate)
  • 如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)。第一范式的目标是确保每列的原子性。
  • 如果一个关系满足1NF,并且除了主键以外的其他列,都依赖于该主键,则满足第二范式(2NF)。第二范式要求每个表只描述一件事情,确保表中的每列,都和主键相关。
  • 如果一个关系满足2NF,并且除了主键以外的其他列都不传递依赖于主键列,则满足第三范式(3NF)。第三范式确保每列都和主键列直接相关,而不是间接相关。




4.数据库存储和查询

首先我们要先将数据库在系统中是怎么样来读取数据的,大概的描述出来,  利用了什么数据结构,将所需要的数据 load 到内存里面? 是全部load ? 还是部分? 还是通过某种方法?
然后怎么来做查询 还有增加删除减少, 这样就可以理解所有的过程了.

http://blog.csdn.net/hguisu/article/details/7786014 


小结:  因为计算机中磁盘的寻址还有转速是影响磁盘的传输时间,还有读取时间, 如果利用红黑树或者 平衡二叉树来作为索引,对磁盘的访问次数会大大的增加,所以我们会采用B+树
这是一种可以减少磁盘I/O 访问的一种数据结构,具体原理他是一棵(平衡多路查找树+有序数组链表)
平衡: B/B+ 都是 每个节点都有m个孩子(m>=2)   (这样就不可能出现二叉树那种偏斜的状况)
多路上面说了是多个孩子, 多路,可以减少树的高度,加快查询的速度.
有序数组链表: 每个叶子节点都是由从小到大的数组  依次的用指针(链) 相连.  这样的作用是可以保存所有的有效信息,便于遍历查找.


B+树是 B树的变形

  •  有 n 棵子树的结点中含有 n-1 个关键字
  • 所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小,自小而大的顺序链接。 (而 B 树的叶子节点并没有包括全部需要查找的信息) ( ps: 因为B+ 比 B 多了一个可以遍历所有叶子节点的操作, 所以保存了全部要查的信息)
  • 所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)
  • B+树的磁盘读写代价更低,B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对 B 树更小。 如果把所有同一内部结点的关键字存放在同一盘块中, 那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说 IO 读写次数也就降低了。

通常在B+树上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点。因此可以对B+树进行两种查找运算:一种是从最小关键字起顺序查找,另一种是从根节点开始,进行随机查找。 在B+树上进行随机查找、插入和删除的过程基本上与B-树类似。只是在查找时,若非终端结点上的关键码等于给定值,并不终止,而是继续向下直到叶子结点。因此,在B+树,不管查找成功与否,每次查找都是走了一条从根到叶子结点的路径。
B-/+Tree检索一次最多需要访问节点:


4.2 索引的原理

 MySQL索引背后的数据结构及算法原理


4.3索引类型

  • 唯一索引:唯一索引不允许两行具有相同的索引值( unique index)
  • 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空(建表的时候建立 , 组合索引 就是多个主键 )
  • 聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个 (InnoDB引擎中创建的主键就是聚集索引)
  • 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个 (mysql 中 create Index... 就是创建的 非聚集索引)



5.事务管理

ACID,是指在数据库管理系统(DBMS)中事务所具有的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

  • 原子性:  事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。  
  • 一致性:  事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应用程序已强制所有已知的完整性约束。例如,当开发用于转帐的应用程序时,应避免在转帐过程中任意移动小数点。  
  • 隔离性: 由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。当事务可序列化时将获得最高的隔离级别。在此级别上,从一组可并行执行的事务获得的结果与通过连续运行每个事务所获得的结果相同。由于高度隔离会限制可并行执行的事务数,所以一些应用程序降低隔离级别以换取更大的吞吐量。   
  • 持久性: 事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。   

5.1锁 

锁的种类:
  • 共享 (S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。 
  • 更新 (U) 用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。 
  • 排它 (X) 用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。 

锁的粒度:
  • 锁粒度是被封锁目标的大小,封锁粒度小则并发性高,但开销大,封锁粒度大则并发性低但开销小 
  • 锁粒度可以分为为行、页、键、键范围、索引、表或数据库获取锁 

避免死锁:

  •  使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务;
  •  设置死锁超时参数为合理范围,如:3分钟-10分种;超过时间,自动放弃本次操作,避免进程悬挂;
  •  优化程序,检查并避免死锁现象出现;


5.2事务隔离机制

来源: <http://blog.csdn.net/gklifg/article/details/38752691>
并发可能会出现下面5类的问题,这个时候就需要我们强大的事务隔离机制来控制.
多个事务同时访问数据库时候,会发生下列5类问题,包括3类数据读问题(脏读,不可重复读,幻读),2类数据更新问题(第一类丢失更新,第二类丢失更新):
  1. 脏读(dirty read):A事务读取B事务尚未提交的更改数据,并在这个数据基础上操作。如果B事务回滚,那么A事务读到的数据根本不是合法的,称为脏读。在oracle中,由于有version控制,不会出现脏读。
  2. 不可重复读(unrepeatable read):A事务读取了B事务已经提交的更改(或删除)数据。比如A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样。
  3. 幻读(phantom read):A事务读取了B事务已经提交的新增数据。注意和不可重复读的区别,这里是新增,不可重复读是更改(或删除)。这两种情况对策是不一样的,对于不可重复读,只需要采取行级锁防止该记录数据被更改或删除,然而对于幻读必须加表级锁,防止在这个表中新增一条数据。
  4. 第一类丢失更新:A事务撤销时,把已提交的B事务的数据覆盖掉。
  5. 第二类丢失更新:A事务提交时,把已提交的B事务的数据覆盖掉。

5.1.1三级封锁协议(在哪里加锁的协议)

    数据库想要在“合适”的时机阻塞住数据库操作,那么首先要定义好怎么样的时机算是“合适”,因为各个系统支持的业务千差万别,对数据的实时性和有效性的要求也不同。于是数据库理论中就提出了封锁级别的概念,对不同的同步要求采用不同的封锁级别。

三级封锁协议内容如下:

  • 一级封锁协议:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。 一级封锁协议可以防止丢失修改,并保证事务T是可恢复的。使用一级封锁协议可以解决丢失修改问题。在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,它不能保证可重复读和不读“脏”数据。 
  • 二级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后方可释放S锁。 二级封锁协议除防止了丢失修改,还可以进一步防止读“脏”数据。但在二级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读。 
  • 三级封锁协议 :一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。 三级封锁协议除防止了丢失修改和不读“脏”数据外,还进一步防止了不可重复读。


遵循协议 隔离级别 丢失的更新 脏 读 不可重复读取 幻 像 一级封锁协议
 未提交读
(Read uncommitted)
    否  是     是  是二级封锁协议
 提交读
(Read committed)
    否  否     是  是二级封锁协议
 可重复读
(Repeatable read)
    否  否     否  是三级封锁协议
 可串行读
(Serializable)
    否  否     否  否

两段锁协议(加锁解锁的协议)

数据库在调度并发事务时遵循“两段锁”协议,“两段锁”协议是指所有事务必须分两个阶段对数据项进行加锁和解锁

  1. 扩展阶段:在对任何数据项的读、写之前,要申请并获得该数据项的封锁。
  2. 收缩阶段:每个事务中,所有的封锁请求必须先于解锁请求

遵循两段锁的调度可以保证调度结果与串行化调度相同。这样的机制保证了数据库并发调度串行调度的等价。


6.mysql 中存储引擎

常用:MyISAM、InnoDB、Heap(Memory)、NDB  其中InnoDB和BDB提供事务安全表,其他存储引擎都是非事务安全表。
最常使用的2种存储引擎:
1.Myisam是Mysql的默认存储引擎,当create创建新表时,未指定新表的存储引擎时,默认使用Myisam。每个MyISAM在磁盘上存储成三个文件。文件名都和表名相同,扩展名分别是.frm(存储表定义)、.MYD(MYData,存储数据)、.MYI(MYIndex,存储索引)。数据文件和索引文件可以放置在不同的目录,平均分布io,获得更快的速度。
2.InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比Myisam的存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。

7.分布式数据库










0 0
原创粉丝点击