MySQL的逻辑架构详解_NeverOW的博客-程序员秘密_mysql逻辑架构

技术标签: 架构  java  MySQL  mysql  后端  数据库  

Mysql逻辑架构

大致分为4层架构:连接层,服务层,引擎层,存储层

连接层

mysql提供给外界客户端连接的接口,不同客户端可以用自己的API连接mysql

  • 建立连接

  • 认证授权

  • 维持和管理连接等

MySQL 驱动

我们的系统是怎么和mysql进行连接和通信的呢?

不可能是平白无故的就能接收和发送请求的吧,此时我们需要了解 MySQL 驱动概念的

就是这个 MySQL 驱动在底层帮我们做了对数据库的连接,只有建立了连接了,才可以发送SQL语句执行CRUD

img

多个连接怎么办?

一次 SQL 请求建立一个连接,多个请求就会建立多个连接

Web系统肯定不是一个人在用,肯定存在多个请求同时去争抢连接的情况!

导致多个请求会去建立数据库连接,然后使用完再都去关闭,这样会有什么问题呢?如下图

java 系统在通过 MySQL 驱动和 MySQL 数据库连接的时候是基于 TCP/IP 协议的

如果每个请求都是新建连接和销毁连接,频繁的创建和销毁连接,造成不必要的浪费和性能下降,非常不合理的。

img

SO

我们需要被提供一些固定的用来连接的线程,这样是不是不需要反复的创建和销毁连接了呢?

没错,说的就是数据库连接池

数据库连接池

  • 维护一定的连接数,方便系统获取连接,使用就去池子中获取,用完放回去就可以了,
  • 我们不需要关心连接的创建与销毁,也不需要关心线程池是怎么去维护这些连接的。

WEB容器中的数据库连接池

  • 我们的 web 系统一般是部署在 tomcat 容器中的,而 t**omcat 是可以并发处理多个请求的**
  • web客户端通过tomcat配置的**常用的数据库连接池(Druid、C3P0、DBCP)**请求连接到mysql的数据库连接池

这就是有名的「池化」思想,例如线程池,HTPP连接池,都能看到它的身影

img

常见的数据库连接池有 Druid、C3P0、DBCP,采用连接池

大大节省了不断创建与销毁线程的开销

这就是有名的「池化」思想,例如线程池,HTPP连接池,都能看到它的身影

MySQL中的数据库连接池

显然,我们mysql系统也不是每次被请求访问,每次都去建立连接

而是从数据库连接池中去获取,解决反复的创建和销毁连接而带来的性能损耗问题

思考:业务系统是并发的,而 MySQL 接受请求的线程呢,只有一个?

其实 MySQL 的架构体系中也已经提供了这样的一个池子,也是数据库连接池

双方都是通过数据库连接池来管理各个连接的:

Web配置的数据库连接池《=连接=》Mysql数据库连接池

  • 一方面不用线程不需要去争抢连接,提高并发性能

  • 一方面减少反复创建销毁线程的消耗

img

至此系统和 MySQL 数据库之间的连接问题已经说明清楚了。那么

MySQL 数据库中的这些连接是怎么来处理的,又是谁来处理呢?

网络连接必须由线程来处理

对计算基础稍微有一点了解的的同学都是知道的,网络中的连接都是由线程来处理的,所谓网络连接说白了就是一次请求,每次请求都会有相应的线程去处理的。

就是说对于 SQL 语句的请求连接成功后,由一个个的线程去获取 SQL 语句去交给 SQL 接口处理

img

总结

  1. web客户端通过tomcat配置的数据库连接池(Druid、C3P0、DBCP)请求连接到mysql的数据库连接池

  2. mysql数据库连接池处理连接请求

  3. 请求成功连接后,由mysql创建的线程去获取sql语句并转交给SQL接口

服务层

总体流程图

img

SQL 接口

  • 负责用来接收用户的 SQL 命令,并返回sql操作结果
  • 数据管理语言和数据定义语言,存储过程,视图,触发器等产生的SQL,并且返回用户需要的查询结果。
  • 比如 select from 就是调用 SQL interface。

查询缓存

简介

查询缓存——它存储SELECT语句以及相应的查询结果集。如果某个查询语句已经位于缓存中,服务器就不会再对查询进行解析、优化、以及执行。这将大大提高系统的性能。

特点

  • 如果查询缓存有命中的查询结果,直接去缓存中取数据
  • 只要有对一个表的更新,这个表上所有的查询缓存都会被清空
  • MySQL 8.0版本直接将查询缓存的整块功能删掉了

如果是查询语句先检查查询缓存,判断缓存里存有一模一样的sql语句?有就是命中,直接返回相应的结果集,没有继续走解析器

解析器(Parser)

SQL是以字符串的形式传过来的,我们要将sql语句解析成mysql自己能认识的语言

流程图

image-20211206221914185

解析过程主要包含以下五个阶段:

  1. 词法分析:
    • 将整个语句拆分成一个个字段
  2. 语法分析:
    • 将词法分析拆分出的字段,按照MySQL定义的语法规则,生成对应的数据结构解析树
  3. 解析树:img
  4. 预处理器:
    • 去进一步的检查解析树是否合法,比如就是去查看表是否存在,列是否存在。
  5. 新解析树:
    • 通过预处理器核对之后生成的新的解析树,新解析树可能和旧解析树结构一致。

查询优化器

mysql根据自己的优化规则,将查询的IO成本和CPU成本消耗降到最低,

  • 在表里面有多个索引的时候,决定使用哪个索引
  • 在一个语句有多表关联(join) 的时候,决定各个表的连接顺序
  • 例如调换where条件位置,使索引满足最佳左前缀法则

优化器执行选出最优索引等步骤后,会去交给执行器调用存储引擎接口,开始去执行被 MySQL 解析过和优化过的 SQL 语句

解释

IO 成本: 即从磁盘把数据加载到内存的成本,MySQL 是以页的形式读取数据的,即当用到某个数据时,并不会只读取这个数据,而会把这个数据相邻的数据也一起读到内存中,这就是有名的程序局部性原理

CPU 成本:数据在内存中查找和排序等 CPU 操作的成本

IO操作复习

  • 数据库的数据文件或者索引文件是以文件形式存在磁盘上的

  • 系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位,

  • innodb将数据读到内存时是以页为基本单位(默认为16KB),

  • 又因为一个磁盘块往往没那么大,所以innodb读磁盘数据时会将总共16KB的连续若干磁盘块读入内存

执行器

  • 所有的操作最终必须通过执行器,会根据表定义的存储引擎定去调用存储引擎对应的接口
  • 执行语句,开始执行的时候,要先判断一下你对这个表T有没有执行查询的权限,没有就返回没有权限的错误,有就继续执行,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。

总结:

img

  1. 客户端发生请求给mysql数据库连接池后,mysql数据库连接池处理请求、完成身份权限验证

  2. 创建线程获取请求中的sql语句,将语句交给sql接口

  3. 如果是查询语句先从查询缓存中查找是否有命中,有就直接返回结果集,没有就走解析器

  4. 解析器将sql语句按规则解析成各个字段,并生成对应的数据结构解析树,然后交给查询优化器,找到最优查找路径,例如选择哪个索引成本最低

  5. 最后交给执行器去调用存储引擎(默认是innodb)对应的结构

存储引擎层

存储引擎层负责了MySQL中数据的存储和提取,服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,可以根据实际需求选取

  • 其架构模式是插件式的,支持InnoDB、MyISAM、 Memory等多个存储引擎。
  • 现在最常用的存储引擎是InnoDB,它从MySQL 5.5.5版本开始成为了 默认存储引擎。如果建表的时候,不指定引擎类型,默认使用InnoDB

种类

  1. InnoDB存储引擎
    InnoDB是MySQL的默认事务型引擎,它被设计用来处理大量的短期(short-lived)事务。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。行级锁,适合高并发情况

  2. MyISAM存储引擎
    MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务和行级锁(myisam改表时会将整个表全锁住),有一个毫无疑问的缺陷就是崩溃后无法安全恢复。

  3. Archive引擎
    Archive存储引擎只支持INSERT和SELECT操作,在MySQL5.1之前不支持索引。
    Archive表适合日志和数据采集类应用。适合低访问量大数据等情况。
    根据英文的测试结论来看,Archive表比MyISAM表要小大约75%,比支持事务处理的InnoDB表小大约83%。

  4. Blackhole引擎
    Blackhole引擎没有实现任何存储机制,它会丢弃所有插入的数据,不做任何保存。但服务器会记录Blackhole表的日志,所以可以用于复制数据到备库,或者简单地记录到日志。但这种应用方式会碰到很多问题,因此并不推荐。

  5. CSV引擎
    CSV引擎可以将普通的CSV文件作为MySQL的表来处理,但不支持索引。
    CSV引擎可以作为一种数据交换的机制,非常有用。
    CSV存储的数据直接可以在操作系统里,用文本编辑器,或者excel读取。

  6. Memory引擎
    如果需要快速地访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory表是非常有用。Memory表至少比MyISAM表要快一个数量级。(使用专业的内存数据库更快,如redis)

  7. Federated引擎
    Federated引擎是访问其他MySQL服务器的一个代理,尽管该引擎看起来提供了一种很好的跨服务器的灵活性,但也经常带来问题,因此默认是禁用的。

存储层

存储层:数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_50596778/article/details/122980967

智能推荐

apk在应用市场上架时需要认领问题的原因和解决办法_列蒙太奇的博客-程序员秘密

有时我们给自己公司的apk上传到各大应用市场的时候,出现需要认领问题。如下图 (搜狗助手应用市场)那么得下载空包及签名说明。打开签名说明:【具体流程】1. 下载待签名空包及签名说明2. 给unsign.apk签名(需要与您将要认领的应用签名一致)【请求技术人员支持】3. 在认领页面第三步提交已签名的unsign.apk4. 认领成功后,该应用会自动转入您的账号下,您

设备端的超市商品识别_ronghuaiyang的博客-程序员秘密

点击上方“AI公园”,关注公众号,选择加“星标“或“置顶”作者:Chao Chen编译:ronghuaiyang导读Google出品的超市商品解决方案。用户面临的最大挑战之一是如何在视觉...

欢乐纪中某B组赛【2019.1.27】_QuantAsk的博客-程序员秘密

前言写完T1T1T1和T2T2T2颓了半天成绩RankRankRank是有算别人的RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC2222017myself2017myself2017myself2302302301001001001001001003030304442017xxy2...

容器 (Java)__重年的博客-程序员秘密

容器ArrayList 和 LinkedList增:void add( Object element); void add (int index, Object element); 删:Object remove (int index); clear() 改:Object set (int index,Object element);//修改某一位置的元素 查:Object get (int index); int indexOf (Object o);//返回某个元素的索

java矩阵相乘泛型_行逻辑链接的顺序表实现稀疏矩阵的相乘(Java语言描述)_复健朱医生的博客-程序员秘密

行逻辑链接,带行链接信息。程序有空指针BUG,至今未解决。还是C/C++适合描述算法数据结构。以后复杂的算法还是改用C/C++吧。有BUG的代码,总有一天会换成没有BUG的。package 行逻辑链接的顺序表实现稀疏矩阵的相乘;public class Triple {int row,col;T v;public Triple(){}public Triple(int row,int col, T...

黑马人工智能怎么样-黑马类达内的资本化教育扩张模式_dfaddaf的博客-程序员秘密

黑马类达内的资本化教育扩张模式解析源于弟弟,他去的就是黑马,当时并没跟家里人说,就跟我提了下,我知道本来他是想找地方学习ui,专业也算比较贴切,但最终却在客服的“劝说下“去学习了人工智能……,还说只学习4-5个月就能成,什么就业没问题,什么未来成为算法工程师,各种工程师职位一大堆。可若人工智能是,学习四五个月能学明白的?如此简单,各地大力投资研发AI干什么?直接让你黑马做,不是更加高效?当初就劝过他不要去,奈何抵不过客服的“糖衣炮弹”,学完出来后,果然找不到工作,而他们所谓的就业老师,给他找的都是写编

随便推点

leetcode刷题.530. 二叉搜索树的最小绝对差.每日打卡_paradox_1_0的博客-程序员秘密

class Solution {public: int threeMin(int a, int b, int c) { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); } int maxTreeNode(TreeNode *root) { while(nullptr != root->right) root = root->...

namecheap,namesilo域名注册优势,国外域名注册,2018 namesilo注册优惠码_brb2_0的博客-程序员秘密

namesilo优惠$1注册优惠码(仅新注册用户):namesilo2018offnamesilo和namecheap的优势都是附赠免费的隐私保护。namesilo注册com平常都是8.99,新用户可凭优惠码优惠1刀。namecheap则有非常多的8.99,新用户可凭优惠码优惠1刀。namecheap则有非常多的8.99,新用户可凭优惠码优惠1刀。namecheap则有非常多的.0.88...

Flink 1.11.1:flink sql kafka-connector示例_TracyGao01的博客-程序员秘密

示例:val createTable = """ |CREATE TABLE nt_sale_order ( | id VARCHAR, | write_date BIGINT, | create_uid INT, | name VARCHAR, | op VARCHAR |) |WITH ( | 'connector' = 'kafka', | 'topic' = 'shopfo

TradingView js api demo (二)生成测试数据_七个包的博客-程序员秘密_tradingview导出数据

这里主要是一个生成高开低收四个数值的脚本,已生成的保存到数据库,最后一条不确定的在redis1,测试数据的表结构,建在basedata数据库下面CREATE TABLE `hedge_basis_mode` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `interval` enum('5m','1h','1d') NOT NU...

Java你可能不知道的事(3)HashMap_程序员yqy的博客-程序员秘密

概述HashMap对于做Java的小伙伴来说太熟悉了。估计你们每天都在使用它。它为什么叫做HashMap?它的内部是怎么实现的呢?为什么我们使用的时候很多情况都是用String作为它的key呢?带着这些疑问让我们来了解HashMap!HashMap介绍1、介绍HashMap是一个用”KEY”-“VALUE”来实现数据存储的类。你可以用一个”key”去存储数据。当你想获得数据的时候,你可以通过”key

【机房重构】——修改密码 及 share()_赵寒的博客-程序员秘密

机房收费系统重构之修改密码,算是自己独立敲出的第一条线,也代表着自己对三层终于有了一定的理解。如何将登陆的用户名记录下来,以供修改密码查找记录时调用。vb中是在模板里定义了一个公共变量,这里应该也是这种思想....但如何定义呢?解决方法:用share关键字。在实体中:Public Shared UserID As String这样就可实现将变量值应用于整个程序。 最初想到这个问题(如何设定一个公共变量),我先想到了:如何让一个变量被赋完值,不再变化(实例化后不是空)。然后我首先

推荐文章

热门文章

相关标签