鼓起勇气开了这个目录,通过MySQL梳理下数据库系统的基本概念和知识,希望能够坚持下来~
什么是数据库?
什么是数据库?数据库、数据库管理系统、数据库系统有什么区别?按照定义,数据库是按照数据结构来组织、存储和管理数据的仓库;数据库管理系统是操作和管理数据库的系统;而数据库系统是包括了数据库、各种软硬件以及相关管理人员的综合系统。从概念上来讲数据库系统大于管理系统大于数据库,然而在实际的使用当中,三者之间的概念经常比较模糊,所以后面笔者都统一称之为数据库系统。
现代数据库系统主要由两部分组成:数据库服务器和数据库内核,其中数据库服务器又包括了两个大的部分:连接控制部分和查询处理部分。总的来讲,数据库系统是一个非常清晰的三层结构,其整体结构如下图所示。
第一层:和客户端连接的交互层,这部分和一般的C/S系统都很类似,主要负责连接处理、用户授权、安全控制等;
第二层:核心功能层,这部分包括了查询解析、分析、优化、缓存、计算等等,所有跨引擎的功能都在这一层实现,例如:存储过程、触发器等;
第三层:存储引擎,负责真实数据的存储和读取,向上提供基本的API供数据库服务器进行调用,我们常说的innodb、tokudb包括最近比较火的rocksdb其实都是存储引擎层,不同的存储引擎向上提供相同的API。
重要概念
在深入了解数据库系统之前,先了解一下数据库中经常听到的几个基本的概念:锁、并发控制、事务、隔离级别。
锁与并发控制
锁和并发控制并不是数据库系统中特有的概念,对于任何有并发访问的系统都或多或少的会使用锁进行并发访问的控制。对于锁,经常听到的有乐观锁、悲观锁、共享锁、排它锁、读锁、写锁、表锁、行锁等等,这些锁到底代表了什么?他们之间又有什么区别?
乐观锁vs悲观锁
乐观锁和悲观锁其实更多的是思想层面的东西。对于乐观锁,其基本思想就是对于同一份数据,总是假设不会有别的进程对其进行修改,所以不需要对数据进行加锁;而悲观锁则是相反,它总是假设别的进程会对当前数据进行修改,所以需要对数据进行加锁。
共享锁vs排它锁
共享锁和排它锁讨论的是加锁方式。读锁和写锁只不过是另一种称呼而已,本质上完全相同。对于共享锁(读锁),如果一个进程对数据加上了共享锁,那么其他进程依然能够对该数据加共享锁,同一个数据被多个进程共享。对于排它锁(写锁),如果一个进程对数据加上了排它锁,那么其他进程不能在对该数据加锁。
表锁vs行锁
表锁和行锁指的是具体的加锁粒度。对于数据库而言,表锁表示对整张表进行加锁,而行锁则是对具体的行进行加锁。介于表锁和行锁之间的还有一种锁叫做页锁,页锁是对一个数据页进行加锁。通常来说,锁的粒度越小越并发控制越好,但是加锁的成本也会更高。
事务
数据库系统与文件系统相比,一个非常重要的特点就是数据库系统支持事务。提到事务,自然免不了事务的四大属性:
原子性(Atomicity)。事务作为数据库系统恢复和并发控制的基本单位,事务中的一组操作要么全部执行要么全部不执行;
一致性(Consistency)。所有的数据必须从一个一致性的状态变为另一个一致性的状态,一致性与原子性紧密关联;
隔离性(Isolation)。事务内的所有操作都不能影响其它事务,即不同事务之间的操作需要相互隔离;
持久性(Durability)。事务一旦提交,其对数据库中数据的改变就是永久性的,其它操作或者故障都不应该对此造成影响。
上述概念看起来并不复杂,大部分接触过数据库的人都能说出ACID,但是真正理解其本质还需要对数据库系统进行深入的了解。
隔离级别
与事务直接相关的另一个概念就是事务的隔离级别,数据库系统中的隔离级别分为四个等级:
未提交读(Read Uncommitted)。一个事务A对某个数据进行修改,此时事务A还未提交,但是另外一个事务B已经能够看到事务A对于该数据的修改。此种隔离级别未对不同事务的操作进行任何隔离。此种事务隔离级别会出现脏读。
已提交读(Read Committed)。一个事务A对某个数据进行修改,此时事务A还未提交,事务B此时无法读取到事务A修改的数据(读到旧值),事务A提交后事务B才能看到对应的修改(读到新值)。此种隔离解决了脏读的问题,但是造成了另外一个问题:事务B前后读到的数据不一致,这种情况也被称为不可重复读。
可重复读(Repeated Read)。可重复读解决了已提交读中的前后读取到的相同数据项值不一致的问题,但是仍然无法解决一个问题:事务B先按照某个条件读取了一批数据,此时事务A插入了一批新的数据并提交,事务B再次按照相同的条件查询时可能会读到新的数据,这种情况被称为幻读。
串行化读(Serializable)。串行化读是事务间最高的隔离级别,不同事务完全按照串行化的方式执行,但是也极大的影响了数据库的并发能力。
MySQL(with innodb)默认的事务隔离级别是可重复读,并且解决了幻读的问题,其基本的实现方式就是通过多版本并发控制(MVCC),关于多版本并发控制,后面将会单独进行介绍。
以上对数据库系统做了一个基本的介绍,后续将对数据库的各个细节部分分别介绍,文中有问题的地方欢迎大家拍砖。