张国伟 发表于 2024-8-20 06:07:33

MySQL数据库

MySQL分为两层Server层和存储引擎层

数据的实行过程是在Server层进行,Server层负责建立毗连、分析和实行SQL语句;存储引擎以及数据存放在存储引擎层,存储引擎层负责数据的存储和提取。

https://i-blog.csdnimg.cn/direct/34fb4bbffe9b490491731cce5cc4ecf6.png
MySQL的实行流程

1.毗连器

职责


[*]通过TCP三次握手使客户端与MySQL服务端进行毗连;
[*]认证:检验登录正当性,如果用户名或密码不对,则会报错;
[*]鉴权:如果用户名和密码正确,登录正当,读取该用户权限,根据权限允许一些操作,权限的管理可以或许细化到表级别;
   如何查察MySQL服务被多少个客户端毗连:show processlist命令,命令实行后会体现客户端的ID、用户名、主机、状态等信息。
空闲毗连会一直占用吗:MySQL界说了空闲毗连的最大空闲时长:wait_timeout参数,默认8小时,凌驾这个时长毗连会自动断开;或手动断开,kill connection +id命令。
MySQL的毗连数有限定吗:最大毗连数由max_connections参数决定,凌驾max_connections会拒绝接下来的毗连,返回报错信息:“Too many connections”
长毗连与断毗连

https://i-blog.csdnimg.cn/direct/91841f5cfabe42c6b891e2c92e03246e.png
长毗连

通过一次的 TCP三次握手 建立毗连,可以实行多条sql语句,待sql语句实行完,通过 TCP四次挥手 断开毗连;避免了毗连多次建立和断开的过程,但是由于断开毗连时资源才会开释,所以长毗连累积过多或导致MySQL服务占用内存太大,可以通过服务端定期断开长毗连与客户端主动重置毗连的方式改善内存占用太大的题目。
优点:淘汰毗连建立和断开的开销
缺点:长时间会占用服务器端的资源,导致资源浪费,如果应用步伐没有正确开释长毗连会导致内存走漏。
   办理方法:心跳机制,在较短的时间间隔内客户端主动将自己的情况报告给服务端(定时发送心跳包),以便于服务端维持或断开长毗连。
短毗连

一次的 TCP三次握手 建立毗连后,只允许一条 sql语句实行,该条sql语句实行完,立即通过 TCP四次挥手 断开毗连,实行下一条sql语句时仍然要建立毗连,毗连及时开释,不会导致资源浪费;
优点:资源开释快速,短毗连在每次请求完成后立即开释毗连资源,不会占用服务器资源。
缺点:频繁建立和断开毗连开销大,服务器压力大。 
2.查询缓存

毗连器工作完成后,客户端就可以向MySQL服务发送SQL语句,如果解析出来的是select查询语句:
MySQL查找服务端建立的缓存表(Query Cache)中是否有对应的缓存数据,如果有则直接返回value效果,如果没有则继承实行,实行完成后,查询的效果就会放入缓存表中。
8.0版本已废除这项功能,若更新表的操作太过频繁,在缓存表中命中效果的概率会降低。原因:一个表有更新操作,那么这个表的查询缓存就会被清空。而且更新缓存时磁盘中的表数据会向缓存中加载,造成磁盘消耗大。
   比方刚刚缓存了一个数据,但是还未使用,表就更行了, 查询缓存就被清空了,前一步的缓存操作就许多余。
3.表明器

在实行sql语句之前,要先进行解析,表明器中重要进行词法分析和语法分析
对于词法分析是将语句分割为一个个关键词,整理关键词与非关键次的数量,为语义分析做铺垫;对于语法分析,根据词法分析的效果,根据语法规则,检查语句的语法是否正确,并构建语法树,关键词是否正确、关键词位置和匹配信息是否正确、逻辑意义是否正确。
4.实行器

经过解析器后,接着就要实行sql语句了。
预处理阶段

对语句进行预处理,检查表或字段是否存在,是在这一阶段完成的。


[*]检查SQL语句的表大概字段是否存在(调用get_table_share()函数)
[*]将select *中的 * 扩展为数据库表中的全部列
优化阶段

为SQL语句选择最佳的索引方式,使其效率最大。
实行阶段

根据优化阶段选择的最佳的索引方式直接实行sql语句
文件的存储布局

底层是B+树,节点中只存放索引key值,具体信息的索引存放在叶子结点的索引中,MySQL采用这样的存储布局可以是的以页为单位的索引中可以存放更多的结点;
 为什么MySQL采用B+树作为存储布局?

磁盘的I/O效率高:B+树的存储布局中非叶子结点存放索引,叶子结点存放真实数据,叶子结点间是双向循环链表,能存储大量数据,尽管记录几万条,B+树的存储布局也是3或4层,MySQL与磁盘的I/O操作也就需要3或4次,磁盘的I/O效率高;
可以范围查询:B+树叶子结点间是双向循环链表,既可以左查询又可以右查询;
插入删除效率高:B+树有大量的冗余节点(全部的非叶子结点都是冗余索引),这些冗余结点让B+树在插入删除效率都很高;比如删除根节点,不会像B树那样会发生复杂树的变革。
   为什么不采用Hash/HashMap这种存储布局而选择B+树呢?
答出以上内容的同时答出:
B+树支持按顺序存储和范围查询,而hash布局不支持范围查询,由于Hash是基于Hash函数盘算的无序存储布局;B+树的内部节点和叶子节点形成有序链表,这使得在实行顺序访问时非常高效,Hash机构没有内在顺序,无法提供顺序访问性能。
HashMap本质上是数组,不可以或许实现范围查询,而且插入删除效率低。
为什么不采用B树这种存储布局而选择B+树呢?
B+Tree 只在叶子节点存储数据,而 B 树 的非叶子节点也要存储数据,所以 B+Tree 的单个节点的数据量更小,在相同的磁盘 I/O 次数下,就能查询更多的节点。
另外,B+Tree 叶子节点采用的是双链表毗连,得当 MySQL 中常见的基于范围的顺序查找,而 B 树无法做到这一点。
为什么不采用二叉树这种存储布局而选择B+树呢?
B+Tree 的高度依然维持在 3~4 层左右,也就是说一次数据查询操作只需要做 3~4 次的磁盘 I/O 操作就能查询到目标数据,而二叉树的每个父节点的儿子节点个数只能是 2 个,意味着其搜索复杂度为 O(logN),这已经比 B+Tree 高出不少,因此二叉树检索到目标数据所履历的磁盘 I/O 次数要更多。
新建表后的存储(非重点)

   比方新建了表my_test,则它的存储目录为/var/lib/mysql/,在/var/lib/mysql/my_test目录中有
#ls /var/lib/mysql/my_test
db.opt
t_order.frm
t_order.ibddb.opt存放数据库默认字符集和字符校验规则
t_order.frm会存放t_order的表布局
t_order.ibd会存放t_order表数据
表空间的文件布局

表空间由段->区->页->行构成,下面是InnoDB的存储布局:
https://i-blog.csdnimg.cn/direct/5dd3ef20ccd7452bbf0f0113b6cc4dfc.png
逐级管理;
MySQL整体的数据布局

数据页/索引页

https://i-blog.csdnimg.cn/direct/e0a7be9ecc1942ef9d97de393c380579.png页格式示意图
文件头

页号:页的标识
校验和:


[*]        形成过程:用hash算法将文件头到文件尾进行Hash盘算,得出的值就是校验和,保存在文件头中。
[*]        作用:检验文件中数据的完整性。当MySQ访问文件时,会先读取文件头部的校验和,并对文件内容重新盘算校验和,如果两者匹配,则文件未被损坏或窜改,数据是完整的,如果不匹配,说明文件是存在题目的。
注意:上一个页的页号和下一个页的页号构成B+树的双向链表。
文件尾

与页头一起校验页的完整性;
页头

第一个标记为删除的记录地址(作用是找到垃圾链表,插入数据);
还未使用空间的最小地址,及最小记录所在的地址;
本页中的记录的数量(包括最小和最大记录以及标记为删除的记录);
页范例;
用户记录

存放实际存储的记录的内容,既有有用记录又有已删除的记录;
用户记录插入数据页中的构造形式:每条记录都有主键,这些记录按照主键顺序排序,这种排序通过页目录和记录的物理位置间接形成有序的数据链表;
slot区(页目录)

基于二分查找的思想计划的,记录页中某些记录的详细的相对位置,为了快速查询。
https://i-blog.csdnimg.cn/direct/ee50298c2364484a828f567e4dfec4d6.png

[*]slot区通过在数据页中选取 特定间隔的记录形成“槽”,并标记序号,这些序号覆盖了整个数据页的范围。每个槽包罗了一个指向页中相应记录的指针(槽中起始记录的主键值)。
[*]查找数据页中的特定记录时,会起首使用二分查找法来搜索slot区,通过比力目标值与页目录中各个槽记录的主键值,迅速缩小查找范围,定位最有可能包罗目标记录的槽。
[*]找到了目标槽,该槽指向的记录开始,通过链表遍历的方式进一步查找并定位到具体的目标记录。
   二分查找:是对有序且存储布局为数组的数据进行查找,其步调:
1.确定数组的起始位置(low)和竣事位置(high);
2.盘算中间位置mid=(low+high)/2;
3.比力并缩小范围:
中间位置的值等于待查找的值,则查找成功,返回该位置
中间位置的值大于待查找的值,说明数据在左半边,更新查找范围,high=mid-1
中间位置的值小于待查找的值,说明数据在右半边,更新查找范围,low=mid+1
4.重复23步调,若low>high,查找范围为空,数组中不存在该值,查找失败;
一行sql记录在Mysql中是如何存储的? 行格式

记录的额外信息

变长字段长度列表:存放记录的真实数据的中变长字段(varchar)的实际长度,以列的顺序的逆序存放。
NULL值列表:存储被NULL修饰的列(XXX is NULL);真实记录数据中每一列对应一个二进制位,二进制位为1时代表该列的值为NULL,为0代表不为NULL;二进制位按照分列顺序的逆序存放;必须使用整数个字节位体现(1byte = 8bit),不足整个字节,高位补0。
记录的头信息



[*]标识此条记录是否被删除:delete_make,若这个记录被删除,delete_make=1
[*]下一条记录的位置:next_record,指向下一个记录的 记录头信息 与 真实数据 之间
[*]当前记录的累心:record_type,0体现普通范例,1体现B+树非叶子结点的记录,2体现最小记录,3体现最大记录 
记录的真实数据

https://i-blog.csdnimg.cn/direct/a6f97d8e65324629bf2436ed8032736f.png
隐蔽列:
row_id :6字节,若建表的时候没有指定主键大概唯一约束列,用row_id标记行
trx_id:6字节,体现数据由哪个事件天生,事件id
roll_pointer:7字节,记录上一个记录的指针
数据列:存储真实的数据

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: MySQL数据库