《从根上理解MySQL》第一章学习笔记
MySQL是怎样运行的:从根上理解MySQL
MySQL进阶学习:
基础前提:学习过基础的SQL语法,查询语句,关键字等等
第一章:装作自己是个小白,重新认识MySQL
使用应用程序实际上就是使用一个客户端和服务器端进行交互。
那么使用MySQL的道理是一样的,使用客户端连接MySQL服务器,发送CURD请求即可
个人思考:这个就很贴近现实了,一般使用MySQL的官方软件MySQLworkbench就是这样:一开始需要连接一个MySQL服务器,还需要输入用户名和密码
服务器程序是直接和数据打交道的,根据客户端的请求来操作响应的数据
一般使用MySQL的流程:
启动MySQL服务器程序,然后启动客户端程序并连接到服务器程序(在我个人的体验中就是现在mac的终端中启动MySQL服务器,然后再在workbench上登陆使用MySQL服务!!man!!!确实如此的!)
一个MySQL服务器程序和客户端程序本质都是一个计算机上的进程,该进程也叫做MySQL数据库实例,建成数据库实例
顺便学习一下计算机操作系统?哈哈哈
进程有一个唯一的编号,PID。该编号由系统随机分配,只是保证每一个进程都不重复而已,关掉进程那么PID就释放掉,可以给另一个进程使用了
进程的名字则是可以人为定义的:比如MySQL服务器进程可以命名为mysqld,客户端进程默认是mysql
总结:我们使用MySQL主要是使用的客户端调用服务器端来执行CURD的数据操作。具体来说就是计算器中的数据库服务器端和客户端进程的使用
客户端 -》 发送CRUD请求 -〉 服务器端 -》 操作数据
——————————————————————————
MySQL安装
安装一般是客户端和服务器端一起安装上了
安装为什么要添加环境变量呢?
因为每次执行一个执行文件都需要在命令行环境中输入一长串的路径,如果使用环境变量的话。系统会自动在/usr/local/bin、/usr/bin:、/bin:、/usr/sbin、/sbin这些目录中查询是否存在我们输入的那个命令,如果查询成功则执行该目录下对应的可执行文件即可
个人感受:这就是环境变量嘛!不是很复杂的什么东西,就是简化掉了可执行文件的路径,直接执行文件嘛
————————————————————————————
启动MySQL服务器程序
在类UNIX系统中启动
类UNIX系统中有很多MySQL服务器程序可以执行的文件,大多数都在MySQL安装目录的bin目录中
比如一个mysqld就是代表MySQL服务器程序,但是这个命令不常用
mysql.server start 这个命令非常熟悉了,指定start参数启动服务器
将start换成stop则可以关掉正在运行的服务器
mysql_multi 一个计算机可以运行多个服务器实例,也就是多个MySQL服务器进程
总结:配置好环境变量以后,直接在命令行中使用相应的可执行文件即可启动服务器端程序
————————————————————————————
启动MySQL客户端程序
启动好了服务器程序接下来就是启动客户端程序来连接这个服务器!!
重点是mysql这个可执行文件
mysql -h -u -p
泪目了,这不就是刚开始学习mysql的时候的启动命令嘛!!
-h代表服务器进程所在的计算机域名或者IP地址,本地一般就是默认地址:127.0.0.1
-u表示用户名
-p代表密码
比如以下这样:
mysql -hlocalhost - uroot -p123456
就可以启动客户端并连接到服务器了
比如像这样就是已经启动成功了,然后你就可以在mysql>
后面尽情输入SQL语句了!!
输入一个quit,可以关闭客户端程序,但是不是关闭服务器端的方式(关闭服务器端可以使用stop)
总结:命令行启动MySQL客户端
————————————————————————————
注意事项
(1)不用直接明文输入密码参数,暂时使用-p替代密码
后续命令行中可以不显示地写出密码
(2)输入参数-p + 密码的时候中间不要有空白字符
(3)mysql启动客户端的命令行参数没有顺序要求
(4)服务器和客户端安装在一台机器上,那么可以省略-h
(5)如果使用的是类UNIX操作系统,那么省略-u系统会自动将登陆操作系统的用户名当作MySQL用户名去处理
————————————————————————————
客户端和服务器连接的过程
客户端和服务器端交互的过程实际上就是进程之间通信的过程:
客户端发送请求消息给服务器端
MySQL支持的客户端进程和服务器进程通信的方式:
(1)TCP/IP
Man!!!!!这个不就是熟知的计算机网络的基本通信协议嘛!TCP负责传输协议,IP负责网络协议Q!!
服务器进程和客户端进程可能在不同的主机中,之间的通信需要借助网络进行。
进程向计算机的操作系统分配一个端口号,然后加上主机IP地址就可以和其他进程连接了!(实际上就是TCP连接四元组:双方的IP地址 + 端口号)
MySQL服务器会默认监听3306端口号,也就是默认申请3306端口号,然后在这个端口号上等待用户的连接
不过启动的时候可以手动指定一个端口号:
mysql -p3307
这样mysql服务器启动的时候就会监听我们指定的端口号了
然后启动客户端的时候也可以指定连接的端口号:使用-P,大写的P来表示希望连接到的端口
启动服务器程序和启动客户端程序都可以使用-P参数
————————————————————————————
命名管道和共享内存
此外Windows可以使用命名管道和共享内存来进行通信
————————————————————————————
Unix域套接字文件
服务器进程和客户端进程都运行在同一台操作系统为类Unix系统的主机上的话,可以使用Unix套接字来进行通信
————————————————————————————
服务器处理客户端请求
上面的几种方式只是实现通信的不同手段,实际上最终得到的效果是客户端发送了一段文本,然后服务器端返回一段文本(处理结果)
这里重点是服务器进程对客户度进程发送的请求做了什么处理才能产生最终的结果呢?
流程大致如下:
客户端 -》服务器端 -〉 连接管理:处理连接 -》 解析和优化:查询缓存 + 语法解析 + 查询优化 -〉 存储引擎 -》 InnoDB -〉 文件系统
总结:客户端通过通信手段和服务器端取得联系,然后发送请求,服务器端再经过各种流程处理请求得到结果再反馈给客户端
————————————————————————————
连接管理:
服务器进程面对每一个客户端发起的连接都会创建一个专门的线程来处理和客户端的交互。客户端退出的时候断开和服务器端的连接,服务器端不会马上删除线程,而是先缓存起来。然后和其他客户端连接的时候再复用这个线程,这样就不用反复创建又销毁线程而到达节省开销的目的
MySQL分配线程多了会影响系统性能,这里是一个优化的点其实
客户端发起连接的时候需要携带主机信息,用户名等相关参数,服务器端会检查认证,没有问题才会连接,还可以使用SSL网络通信来确保数据传输安全(客户端和服务器端在不同的主机的时候)
建立连接以后服务器端就陆续收到客户端的文本请求消息了,文本消息还要经过处理
总结:服务器端通过分配线程和客户端进行交互,线程具有缓存复用机制可以避免性能开销过大,同时连接的时候还可以使用参数验证和SSL来保证通信安全
————————————————————————————
解析和优化
到现在服务器端已经收到了文本形式的请求,但是还需要经过各种处理,其中比较重要的部分是查询缓存,语法解析,查询优化
————————————————————————————
查询缓存
Cos60°是多少?很多人脱口而出是0.5嘛,这怎么了。如果你没有学过呢?还可以脱口而出吗?你学过并且反复用过,大脑已经牢牢记住了这个结论因此再遇到这个问题的时候可以脱口而出答案了
这就是缓存机制!!刚刚实际上走的是达到的记忆内存,也就是直接走缓存而不用重新推导得出答案了
MySQL程序处理查询请求也是这样,之前处理过的请求和结果放到缓存中,如果下次有一样的请求过来那么直接走这个缓存即可,就不用再一遍遍的去数据库中找了
并且缓存可以共享,A查询过的东西留在缓存中,B再次请求也可以走A留下的缓存
但是MySQL不是那么灵活,如果查询有一点点不同都会导致缓存不命中——比如空格,或者大小写之类这种很细节的地方不同的话
而且如果查询的请求中有系统表或者系统函数或者用户自定义的变量和函数,那么该次请求就不会缓存。比如NOW用于查询当前时间,这个时候再走缓存不是过了老期了嘛哈哈哈哈
缓存总是会失效的,MySQL的缓存系统的失效机制是:检测每张表,只要有修改就使它过期!!
个人思考:man!!!这个不就和我的blog项目的思路是一样的嘛!我在blog中的缓存也是只要数据库中有修改那么就删除缓存,有时还需要用到延迟双删的方法来确保缓存和数据库数据一致
查询缓存可以提高响应,但是维护缓存也会有性能开销,从MySQL5.7.20开始不推荐使用查询缓存了,并在MySQL8.0中被删除
总结:相同的查询直接走缓存!
————————————————————————————
语法解析
缓存没有命中,那么接下来正式开始进入查询阶段。服务器端先对文本进行解析,判断语法,然后将要查询的表和各种查询条件都提取出来放到内部使用的一些数据结构上来
注意:指定1文本中提取信息实际上是一个编译过程,知道就行不用深究
总结就是:服务器端通过文本消息得到了能被识别到的查询信息
————————————————————————————
查询优化
服务器得到了查询信息:比如要查询的列和表,查询条件等等。不过这是我们客户端输入的信息,效率可能不是很高。服务器端会自动帮助优化查询,也就是预处理。比如将外连接转换为内连接,简化表达式,子查询转换连接等等。
优化得到一个执行计划,表明了应该使用哪些索引进行查询,以及表之间的连接顺序是怎样的。
总结:得到用户的指令以后,服务器端再在自己的理解上进一步优化查询
个人思考:比如一个数学问题要你证明线面垂直,你经过脑子里的转换和优化知道:哦,那么在这个题中就是要证明某具体两条线的某种几何关系即可了!
也就是脑子里进行一种“翻译”,预处理,在原请求的基础上更进一步得到更加具体的请求任务
————————————————————————————
存储引擎
直到查询优化服务器端都没有真正访问真实的数据表。MySQL服务器将数据的存储和提取操作都封装到了一个存储引擎的东西里。
表是一行一行的记录组成的,但是物理如何表示记录呢?怎么讲表中的数据写到具体的物理存储器上呢,这都是存储引擎负责的事情。为了不同的功能实现MySQL准备了不同的存储引擎来满足不同的需求。那么使用的算法和存储结构也不一定相同
个人思考:存储引擎我感觉就是沟通软件数据库层面和物理层面的一个服务,MySQL将具体方法封装到了引擎中,这样通过存储引擎直接支配物理层进行数据的操作!!
引擎实际上就是表处理器,接收上层传达下来的命令,然后对表中的数据进行相应的操作
为了方便起见,人们将连接管理,查询缓存,语法解析,查询优化,这些不涉及真实数据存储的功能划分为MySQL server的功能,将真实存储的功能划分为存储引擎的功能。
各种存储引擎直接面对上层的server调用接口(存储引擎API),包含了很多底层的函数
MySQL server完成了查询优化以后,按照生成的计划调用底层存储引擎API即可得到结果,再返回给用户即可
总结:
存储引擎是负责具体底层的物理数据操作实现的,它由上层的server接口支配。server负责根据查询信息生成的计划调用相应的接口方法来得到结果反馈给用户
————————————————————————————
常见的存储引擎
很多,最常见的就是InnoDB和MyISAM
InnoDB是MySQL的默认引擎,具备外键支持功能的事物存储引擎
————————————————————————————
关于存储引擎的一些操作
SHOW ENGINES;可以查看当前服务器支持的存储引擎
————————————————————————————
设置表的存储引擎
不同的表可以自定义不同的存储引擎来管理
————————————————————————————
创建表时指定存储引擎
CREATE TABLE xxx(
建表语句
)ENGINE = 存储引擎名字;
————————————————————————————
修改表的存储引擎
ALTER TABLE xxx ENGINE = 存储引擎名字;
——————————————————————END——————————————————————
