01_系统是如何与 MySQL 打交道的
约 903 字大约 3 分钟
2024-08-10
平时我们做 Java 系统,一般都会连接一个 MySQL 数据库,然后去建库建表建索引,做各种增删改查
如果遇到死锁异常、SQL性能差、异常报错等问题就去搜索然后解决,虽然解决了问题但是可能也没太搞明白其中的原理,对 MySQL 的理解基本就停留在下面这样的阶段

本文档旨在带大家一起探索 MySQL 底层原理的方方面面,以及在探索解决 MySQL 各种生产案例问题的时候,如何基于 MySQL 底层原理去分析、排查和定位
MySQL 驱动
在 Java 系统中如果我们要去访问 MySQL 数据库,我们就会在系统中引入一个 MySQL 驱动的依赖,Maven 中引入 MySQL 驱动依赖的配置如下
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>MySQL 驱动会在底层和 MySQL 数据库建立网络连接,有了网络连接就可以发送请求给数据库服务器,执行我们 Java 代码中的增删改查

MySQL 会提供对应开发语言的 MySQL 驱动,Java 有 Java 版本的 MySQL 驱动,Go、Python 也会有对应版本的 MySQL 驱动,旨在让各种语言的系统都可以通过 MySQL 驱动去访问 MySQL 数据库
数据库连接池
我们先思考一个问题,一个 Java 系统只和数据库建立一个连接吗?
假设我们用 Java 开发的一个 Web 系统是部署在 Tomcat 中的,Tomcat 本身是有多个线程并发处理请求的,那并发处理请求的时候都要去争抢一个连接去访问数据库的话,那效率肯定是很低下的,这样不行
那么 Tomcat 中每个线程每次访问数据库的时候,都基于 MySQL 驱动去建立一个数据库连接,然后执行完 SQL 之后再销毁这个连接,这样行不行?
每次建立一个数据库连接都很耗时,Tomcat 中可能有上百个线程,这么频繁的创建、销毁数据库连接肯定也是不行的
所以我们必须要使用一个数据库连接池,也就是说在一个池子里维持多个数据库连接
让多个线程使用连接池中不同的连接去执行 SQL,执行完之后不销毁这个数据库连接,而是把连接放回池子里,后面继续使用,如下图所示

基于数据库连接池机制,避免了数据库连接的频繁创建、销毁的开销,常见的数据库连接池有 Durid、C3P0 等等
MySQL 数据库连接池
一个 MySQL 数据库可能与多个系统建立很多个连接,那 MySQL 肯定也要维护与系统之间的的多个连接,所以 MySQL 架构体系中的第一个环节就是连接池,如下图所示

MySQL 数据库连接池就是维护与多个系统之间的多个连接,系统每次与 MySQL 建立连接的时候,还会根据传递过来的账号密码进行账号密码验证,以及库表权限的验证