一、Mysql是什么

Mysql是当今世界上最流行的数据库系统。由于强大、灵活、开源免费的特性,Mysql连续几年都雄踞数据库排行榜首位。

二、Mysql结构的一些简要介绍

1.Mysql逻辑架构

分三层: - 最上层:网络层,比如连接处理、授权认证、安全等 - 中间层:核心服务层,包括各种查询解析、分析优化、缓存以及各种内置函数等,所有跨存储引擎的功能都在这一层,如存储过程、触发器、视图等。 - 最底层:存储引擎层,负责数据的存储和提取,注意,Mysql包含了多套存储引擎,还支持扩展接口来使用外部的第三方引擎,所有的存储引擎都只与中间层交互,相互之间不会通信,每个表都可以设定不同的存储引擎。这是Mysql具有灵活性的优点,当然同时也增加了人们的学习和选择成本。

2.连接管理和安全性

每个客户端的连接都会在服务器进程中拥有一个线程,连接的查询在这个线程中单独进行。 服务器会负责缓存线程,不需要为连接创建和销毁线程。(5.5版本还支持线程池插件) 认证就是SSL和X.509证书认证,安全性具体内容后期会有章节介绍。

3.中间层的优化器和查询缓存

中间层有个优化器,负责在解释器解析SQL语句后进行各种优化,比如决定表的读取顺序,选择合适的索引等。 该优化器是不关心使用什么存储引擎的,(废话,它在中间层里),但是存储引擎还是会对优化器造成影响,有时候优化器会根据存储引擎返回的信息来作出决策。 对于SELECT查询语句,不会直接去存储引擎拿数据,中间层会先看一下查询缓存有没有已经执行过的查询,如果有,就不需要再经过解释优化和执行的整个过程,而是直接去取缓存中的结果集返回。

三、Mysql面对并发

和大多数数据库系统一样,面对并发问题,不可避免要使用到锁,因此先简要介绍一下锁的概念吧。 ## 1.读写锁 - 读锁(又称共享锁):当某资源加读锁时,多个用户都可同时读取该资源,互不干扰,但是不能写入数据; - 写锁(又称排它锁):当某资源加写锁时,除了持有锁的用户,其他的用户既不能读,也不能写。

2.锁粒度

Mysql由于采用了多种存储引擎,每种引擎有自己的锁策略和锁粒度。常见的锁粒度有以下两种: - 表锁:Mysql中最常见的锁策略,开销最小,但是一旦加锁,整张表的数据都将受到锁的影响,不利于高并发。写锁优先级会高于读锁,因此写锁请求有时候会被自动插入到读锁请求队列的前面。中间层有时候也会加表锁,如ALTER TABLE语句。 - 行锁:可支持高并发,但是由于锁定的是行,肯定要做很多多余的事情,开销很大。在Mysql中,只有存储引擎实现行锁,中间层不会行锁。InnoDB和XtraDB存储引擎(还有其他一些作者懒得提名字的)实现了行锁。

四、事务是数据库永恒的话题

事务就是一组满足ACID特性的查询语句或者工作单元。 一个事务只有两个动作:提交(commit)和回退(rollback) - A(原子性):原子,顾名思义,曾经被认为是最小的不可分割的元素。事务也是如此,事务中所有的操作不可被分隔成两部分,要么都提交,要么都回退。 - C(一致性):一个事务无论是提交还是回退,都不会破坏数据库数据状态的一致性。 - I(隔离性):事务相互之间一点儿关系都没有,谁也不能影响谁 - D(持久性):事务一旦提交,所做的修改就要永久地改变,即使系统崩溃也不会丢失。

不是所有的数据库都支持事务的。同样的,Mysql众多的存储引擎中,不是所有的都支持事务的。最常用的InnoDB完美地支持事务。 然而,支持事务不一定是好事,有些不需要事务的场景,应该使用不支持事务的引擎,因为,要支持事务,数据库服务器要多做很多事情,这是有开销的,和锁机制一样。

五、四种隔离级别

隔离级别是SQL标准定义的,主要针对支持事务的数据库而言,有下面四种:

  1. READ UNCOMMITTED 未提交读:这个级别代表即使事务没有提交,事务的更改也可以被其他的事务读到,因此叫未提交读。这是最弱的隔离级别,还未提交的数据有可能回滚,而其他事务却在回滚之前读到了未提交的数据,这种现象叫做脏读。大多数情况下,都不推荐使用该隔离级别,会造成数据问题,而性能方面提高不了多少。

  2. READ COMMITTED 提交读:大多数数据库默认的隔离级别就是提交读。这个级别代表事务开始后,只能读到其他事务提交后的修改,未提交的修改是不可见的。显然这样就解决了脏读的问题。但是还是会遇到不可重复读的问题。 不可重复读是说一个事务在读取某数据后,在还未结束前,该数据被其他事务修改了,并且其他事务已经提交。此时事务再次读取数据,会发现自己之前读的数据变了。在一次事务中两次读取同一个数据,结果可能会不一致。